msgset: implement "foreach" calls.
* imap4d/copy.c (copy_env) <src>: Remove. Not needed now. (size_sum,do_copy): Change to a mu_msgset_message_action_t. (try_copy,safe_copy): Change signature; use mu_msgset_foreach_message. * imap4d/fetch.c (_fetch_from_message): Change to a mu_msgset_message_action_t. (imap4d_fetch0): Use mu_msgset_foreach_message. * imap4d/imap4d.h (imap4d_message_action_t): Remove typedef. (util_foreach_message): Remove. Use mu_msgset_foreach_message. * imap4d/store.c (_do_store): Change to a mu_msgset_message_action_t. (imap4d_store0): Use mu_msgset_foreach_message. * imap4d/util.c (util_foreach_message): Remove. * include/mailutils/list.h (mu_list_foreach_dir): New proto. * include/mailutils/msgset.h (mu_msgset_msgno_action_t) (mu_msgset_message_action_t): New typedefs. (mu_msgset_negate,mu_msgset_foreach_dir_msgno) (mu_msgset_foreach_msgno,mu_msgset_foreach_dir_message) (mu_msgset_foreach_message): New protos. * libmailutils/list/foreachdir.c: New file. * libmailutils/list/Makefile.am (liblist_la_SOURCES): Add foreachdir.c. * libmailutils/list/head.c (mu_list_head): Fix conditional. * libmailutils/list/tail.c (mu_list_tail): Likewise. * libmailutils/msgset/foreachmsg.c: New file. * libmailutils/msgset/foreachnum.c: New file. * libmailutils/msgset/negate.c: New file. * libmailutils/msgset/Makefile.am (libmsgset_la_SOURCES): Add new files. * libmailutils/msgset/getitr.c (mu_msgset_get_iterator): Call mu_msgset_aggregate before doing anything. * libmailutils/msgset/getlist.c (mu_msgset_get_list): Likewise. * libmailutils/msgset/locate.c (mu_msgset_locate): Likewise. * libmailutils/msgset/parse.c (parse_msgrange): Remove duplicated code. * testsuite/msgset.c: Implement -neg option.
Showing
20 changed files
with
402 additions
and
104 deletions
... | @@ -58,57 +58,35 @@ imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -58,57 +58,35 @@ imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok) |
58 | struct copy_env | 58 | struct copy_env |
59 | { | 59 | { |
60 | mu_mailbox_t dst; | 60 | mu_mailbox_t dst; |
61 | mu_mailbox_t src; | ||
62 | mu_off_t total; | 61 | mu_off_t total; |
63 | int ret; | 62 | int ret; |
64 | char **err_text; | 63 | char **err_text; |
65 | }; | 64 | }; |
66 | 65 | ||
67 | static int | 66 | static int |
68 | size_sum (size_t msgno, void *data) | 67 | size_sum (size_t msgno, mu_message_t msg, void *data) |
69 | { | 68 | { |
70 | struct copy_env *env = data; | 69 | struct copy_env *env = data; |
71 | mu_message_t msg = NULL; | ||
72 | int rc; | 70 | int rc; |
73 | 71 | ||
74 | rc = mu_mailbox_get_message (env->src, msgno, &msg); | 72 | size_t size; |
73 | rc = mu_message_size (msg, &size); | ||
75 | if (rc) | 74 | if (rc) |
76 | { | 75 | { |
77 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_message", NULL, rc); | 76 | mu_diag_funcall (MU_DIAG_ERROR, "mu_message_size", NULL, rc); |
78 | env->ret = RESP_NO; | 77 | env->ret = RESP_BAD; |
79 | return MU_ERR_FAILURE; | 78 | return MU_ERR_FAILURE; |
80 | } | 79 | } |
81 | else | 80 | env->total += size; |
82 | { | ||
83 | size_t size; | ||
84 | rc = mu_message_size (msg, &size); | ||
85 | if (rc) | ||
86 | { | ||
87 | mu_diag_funcall (MU_DIAG_ERROR, "mu_message_size", NULL, rc); | ||
88 | env->ret = RESP_BAD; | ||
89 | return MU_ERR_FAILURE; | ||
90 | } | ||
91 | env->total += size; | ||
92 | } | ||
93 | return 0; | 81 | return 0; |
94 | } | 82 | } |
95 | 83 | ||
96 | static int | 84 | static int |
97 | do_copy (size_t msgno, void *data) | 85 | do_copy (size_t msgno, mu_message_t msg, void *data) |
98 | { | 86 | { |
99 | struct copy_env *env = data; | 87 | struct copy_env *env = data; |
100 | mu_message_t msg = NULL; | ||
101 | int status; | 88 | int status; |
102 | 89 | ||
103 | status = mu_mailbox_get_message (env->src, msgno, &msg); | ||
104 | if (status) | ||
105 | { | ||
106 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_message", NULL, | ||
107 | status); | ||
108 | env->ret = RESP_BAD; | ||
109 | return MU_ERR_FAILURE; | ||
110 | } | ||
111 | |||
112 | imap4d_enter_critical (); | 90 | imap4d_enter_critical (); |
113 | status = mu_mailbox_append_message (env->dst, msg); | 91 | status = mu_mailbox_append_message (env->dst, msg); |
114 | imap4d_leave_critical (); | 92 | imap4d_leave_critical (); |
... | @@ -124,14 +102,12 @@ do_copy (size_t msgno, void *data) | ... | @@ -124,14 +102,12 @@ do_copy (size_t msgno, void *data) |
124 | } | 102 | } |
125 | 103 | ||
126 | static int | 104 | static int |
127 | try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, | 105 | try_copy (mu_mailbox_t dst, mu_msgset_t msgset, char **err_text) |
128 | char **err_text) | ||
129 | { | 106 | { |
130 | int rc; | 107 | int rc; |
131 | struct copy_env env; | 108 | struct copy_env env; |
132 | 109 | ||
133 | env.dst = dst; | 110 | env.dst = dst; |
134 | env.src = src; | ||
135 | env.total = 0; | 111 | env.total = 0; |
136 | env.ret = RESP_OK; | 112 | env.ret = RESP_OK; |
137 | env.err_text = err_text; | 113 | env.err_text = err_text; |
... | @@ -139,7 +115,7 @@ try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, | ... | @@ -139,7 +115,7 @@ try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, |
139 | *env.err_text = "Operation failed"; | 115 | *env.err_text = "Operation failed"; |
140 | 116 | ||
141 | /* Check size */ | 117 | /* Check size */ |
142 | rc = util_foreach_message (msgset, size_sum, &env); | 118 | rc = mu_msgset_foreach_message (msgset, size_sum, &env); |
143 | if (rc) | 119 | if (rc) |
144 | return RESP_NO; | 120 | return RESP_NO; |
145 | if (env.ret != RESP_OK) | 121 | if (env.ret != RESP_OK) |
... | @@ -151,7 +127,7 @@ try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, | ... | @@ -151,7 +127,7 @@ try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, |
151 | return RESP_NO; | 127 | return RESP_NO; |
152 | } | 128 | } |
153 | env.total = 0; | 129 | env.total = 0; |
154 | rc = util_foreach_message (msgset, do_copy, &env); | 130 | rc = mu_msgset_foreach_message (msgset, do_copy, &env); |
155 | quota_update (env.total); | 131 | quota_update (env.total); |
156 | if (rc) | 132 | if (rc) |
157 | return RESP_NO; | 133 | return RESP_NO; |
... | @@ -159,8 +135,7 @@ try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, | ... | @@ -159,8 +135,7 @@ try_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, |
159 | } | 135 | } |
160 | 136 | ||
161 | static int | 137 | static int |
162 | safe_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, | 138 | safe_copy (mu_mailbox_t dst, mu_msgset_t msgset, char **err_text) |
163 | char **err_text) | ||
164 | { | 139 | { |
165 | size_t nmesg; | 140 | size_t nmesg; |
166 | int status; | 141 | int status; |
... | @@ -174,7 +149,7 @@ safe_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, | ... | @@ -174,7 +149,7 @@ safe_copy (mu_mailbox_t dst, mu_mailbox_t src, mu_msgset_t msgset, |
174 | return RESP_NO; | 149 | return RESP_NO; |
175 | } | 150 | } |
176 | 151 | ||
177 | status = try_copy (dst, src, msgset, err_text); | 152 | status = try_copy (dst, msgset, err_text); |
178 | if (status != RESP_OK) | 153 | if (status != RESP_OK) |
179 | { | 154 | { |
180 | size_t maxmesg; | 155 | size_t maxmesg; |
... | @@ -283,7 +258,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -283,7 +258,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
283 | mu_list_t msglist; | 258 | mu_list_t msglist; |
284 | mu_msgset_get_list (msgset, &msglist); | 259 | mu_msgset_get_list (msgset, &msglist); |
285 | if (!mu_list_is_empty (msglist)) | 260 | if (!mu_list_is_empty (msglist)) |
286 | status = safe_copy (cmbox, mbox, msgset, err_text); | 261 | status = safe_copy (cmbox, msgset, err_text); |
287 | mu_mailbox_close (cmbox); | 262 | mu_mailbox_close (cmbox); |
288 | } | 263 | } |
289 | mu_mailbox_destroy (&cmbox); | 264 | mu_mailbox_destroy (&cmbox); | ... | ... |
... | @@ -1783,19 +1783,19 @@ fetch_thunk (imap4d_parsebuf_t pb) | ... | @@ -1783,19 +1783,19 @@ fetch_thunk (imap4d_parsebuf_t pb) |
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | int | 1785 | int |
1786 | _fetch_from_message (size_t msgno, void *data) | 1786 | _fetch_from_message (size_t msgno, mu_message_t msg, void *data) |
1787 | { | 1787 | { |
1788 | int rc = 0; | 1788 | int rc = 0; |
1789 | struct fetch_runtime_closure *frc = data; | 1789 | struct fetch_runtime_closure *frc = data; |
1790 | 1790 | ||
1791 | frc->msgno = msgno; | 1791 | frc->msgno = msgno; |
1792 | if (mu_mailbox_get_message (mbox, msgno, &frc->msg) == 0) | 1792 | frc->msg = msg; |
1793 | { | 1793 | |
1794 | io_sendf ("* %lu FETCH (", (unsigned long) msgno); | 1794 | io_sendf ("* %lu FETCH (", (unsigned long) msgno); |
1795 | frc->eltno = 0; | 1795 | frc->eltno = 0; |
1796 | rc = mu_list_foreach (frc->fnlist, _do_fetch, frc); | 1796 | rc = mu_list_foreach (frc->fnlist, _do_fetch, frc); |
1797 | io_sendf (")\n"); | 1797 | io_sendf (")\n"); |
1798 | } | 1798 | |
1799 | return rc; | 1799 | return rc; |
1800 | } | 1800 | } |
1801 | 1801 | ||
... | @@ -1833,7 +1833,7 @@ imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -1833,7 +1833,7 @@ imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
1833 | loop below */ | 1833 | loop below */ |
1834 | frc.err_text = "Completed"; | 1834 | frc.err_text = "Completed"; |
1835 | 1835 | ||
1836 | util_foreach_message (pclos.msgset, _fetch_from_message, &frc); | 1836 | mu_msgset_foreach_message (pclos.msgset, _fetch_from_message, &frc); |
1837 | mu_list_destroy (&frc.msglist); | 1837 | mu_list_destroy (&frc.msglist); |
1838 | } | 1838 | } |
1839 | 1839 | ... | ... |
... | @@ -372,11 +372,6 @@ extern char *util_getfullpath (const char *); | ... | @@ -372,11 +372,6 @@ extern char *util_getfullpath (const char *); |
372 | extern struct imap4d_command *util_getcommand (char *, | 372 | extern struct imap4d_command *util_getcommand (char *, |
373 | struct imap4d_command []); | 373 | struct imap4d_command []); |
374 | 374 | ||
375 | typedef int (*imap4d_message_action_t) (size_t, void *); | ||
376 | |||
377 | int util_foreach_message (mu_msgset_t list, imap4d_message_action_t action, | ||
378 | void *data); | ||
379 | |||
380 | enum datetime_parse_mode /* how to parse date/time strings */ | 375 | enum datetime_parse_mode /* how to parse date/time strings */ |
381 | { | 376 | { |
382 | datetime_default, /* default mode */ | 377 | datetime_default, /* default mode */ | ... | ... |
... | @@ -91,13 +91,11 @@ store_thunk (imap4d_parsebuf_t p) | ... | @@ -91,13 +91,11 @@ store_thunk (imap4d_parsebuf_t p) |
91 | } | 91 | } |
92 | 92 | ||
93 | static int | 93 | static int |
94 | _do_store (size_t msgno, void *data) | 94 | _do_store (size_t msgno, mu_message_t msg, void *data) |
95 | { | 95 | { |
96 | struct store_parse_closure *pclos = data; | 96 | struct store_parse_closure *pclos = data; |
97 | mu_message_t msg = NULL; | ||
98 | mu_attribute_t attr = NULL; | 97 | mu_attribute_t attr = NULL; |
99 | 98 | ||
100 | mu_mailbox_get_message (mbox, msgno, &msg); | ||
101 | mu_message_get_attribute (msg, &attr); | 99 | mu_message_get_attribute (msg, &attr); |
102 | 100 | ||
103 | switch (pclos->how) | 101 | switch (pclos->how) |
... | @@ -154,7 +152,7 @@ imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext) | ... | @@ -154,7 +152,7 @@ imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext) |
154 | ptext); | 152 | ptext); |
155 | if (rc == RESP_OK) | 153 | if (rc == RESP_OK) |
156 | { | 154 | { |
157 | util_foreach_message (pclos.msgset, _do_store, &pclos); | 155 | mu_msgset_foreach_message (pclos.msgset, _do_store, &pclos); |
158 | 156 | ||
159 | *ptext = "Completed"; | 157 | *ptext = "Completed"; |
160 | } | 158 | } | ... | ... |
... | @@ -39,42 +39,6 @@ util_getfullpath (const char *name) | ... | @@ -39,42 +39,6 @@ util_getfullpath (const char *name) |
39 | return mu_normalize_path (exp); | 39 | return mu_normalize_path (exp); |
40 | } | 40 | } |
41 | 41 | ||
42 | struct action_closure | ||
43 | { | ||
44 | imap4d_message_action_t action; | ||
45 | void *data; | ||
46 | }; | ||
47 | |||
48 | static int | ||
49 | procrange (void *item, void *data) | ||
50 | { | ||
51 | struct mu_msgrange *mp = item; | ||
52 | struct action_closure *clos = data; | ||
53 | size_t i; | ||
54 | |||
55 | for (i = mp->msg_beg; i <= mp->msg_end; i++) | ||
56 | { | ||
57 | int rc = clos->action (i, clos->data); | ||
58 | if (rc) | ||
59 | return rc; | ||
60 | } | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | /* Apply ACTION to each message number from LIST. */ | ||
65 | int | ||
66 | util_foreach_message (mu_msgset_t msgset, imap4d_message_action_t action, | ||
67 | void *data) | ||
68 | { | ||
69 | mu_list_t list; | ||
70 | struct action_closure clos; | ||
71 | |||
72 | clos.action = action; | ||
73 | clos.data = data; | ||
74 | mu_msgset_get_list (msgset, &list); | ||
75 | return mu_list_foreach (list, procrange, &clos); | ||
76 | } | ||
77 | |||
78 | int | 42 | int |
79 | util_do_command (imap4d_tokbuf_t tok) | 43 | util_do_command (imap4d_tokbuf_t tok) |
80 | { | 44 | { | ... | ... |
... | @@ -144,10 +144,15 @@ int mu_list_get_iterator (mu_list_t _list, mu_iterator_t *_pitr); | ... | @@ -144,10 +144,15 @@ int mu_list_get_iterator (mu_list_t _list, mu_iterator_t *_pitr); |
144 | typedef int (*mu_list_action_t) (void *_item, void *_data); | 144 | typedef int (*mu_list_action_t) (void *_item, void *_data); |
145 | 145 | ||
146 | /* Execute _action for each element in _list. Use _data as the call-specific | 146 | /* Execute _action for each element in _list. Use _data as the call-specific |
147 | data. */ | 147 | data. If _dir is 0, traverse the list from head to tail. If it is 1, |
148 | traverse it in the reverse direction */ | ||
149 | int mu_list_foreach_dir (mu_list_t _list, int _dir, mu_list_action_t _action, | ||
150 | void *_cbdata); | ||
151 | /* Same as mu_list_foreach_dir with _dir==0. */ | ||
148 | int mu_list_foreach (mu_list_t _list, mu_list_action_t _action, void *_data); | 152 | int mu_list_foreach (mu_list_t _list, mu_list_action_t _action, void *_data); |
149 | /* A historical alias to the above. */ | 153 | /* A historical alias to the above. */ |
150 | int mu_list_do (mu_list_t, mu_list_action_t, void *) MU_DEPRECATED; | 154 | int mu_list_do (mu_list_t, mu_list_action_t, void *) MU_DEPRECATED; |
155 | |||
151 | 156 | ||
152 | /* ************************************************* */ | 157 | /* ************************************************* */ |
153 | /* Functions for combining two lists. */ | 158 | /* Functions for combining two lists. */ | ... | ... |
... | @@ -33,7 +33,7 @@ struct mu_msgrange | ... | @@ -33,7 +33,7 @@ struct mu_msgrange |
33 | #define MU_MSGNO_LAST 0 | 33 | #define MU_MSGNO_LAST 0 |
34 | 34 | ||
35 | #define MU_MSGSET_UID 0x01 /* Message set operates on UIDs */ | 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 | int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int flags); |
38 | int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist); | 38 | 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); | 39 | int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr); |
... | @@ -53,6 +53,26 @@ int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset); | ... | @@ -53,6 +53,26 @@ int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset); |
53 | 53 | ||
54 | int mu_msgset_locate (mu_msgset_t msgset, size_t n, | 54 | int mu_msgset_locate (mu_msgset_t msgset, size_t n, |
55 | struct mu_msgrange const **prange); | 55 | struct mu_msgrange const **prange); |
56 | |||
57 | int mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset); | ||
58 | |||
59 | 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, | ||
61 | void *_call_data); | ||
62 | |||
63 | int mu_msgset_foreach_dir_msgno (mu_msgset_t _msgset, int _dir, | ||
64 | mu_msgset_msgno_action_t _action, | ||
65 | void *_data); | ||
66 | int mu_msgset_foreach_msgno (mu_msgset_t _msgset, | ||
67 | mu_msgset_msgno_action_t _action, | ||
68 | void *_call_data); | ||
69 | int mu_msgset_foreach_dir_message (mu_msgset_t _msgset, int _dir, | ||
70 | mu_msgset_message_action_t _action, | ||
71 | void *_call_data); | ||
72 | int mu_msgset_foreach_message (mu_msgset_t _msgset, | ||
73 | mu_msgset_message_action_t _action, | ||
74 | void *_call_data); | ||
75 | |||
56 | 76 | ||
57 | #ifdef __cplusplus | 77 | #ifdef __cplusplus |
58 | } | 78 | } | ... | ... |
libmailutils/list/foreachdir.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010, 2011 | ||
3 | Free Software Foundation, Inc. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 3 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General | ||
16 | Public License along with this library. If not, see | ||
17 | <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | #include <stdlib.h> | ||
23 | #include <mailutils/sys/list.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | |||
26 | int | ||
27 | mu_list_foreach_dir (mu_list_t list, int dir, | ||
28 | mu_list_action_t action, void *cbdata) | ||
29 | { | ||
30 | mu_iterator_t itr; | ||
31 | int status = 0; | ||
32 | |||
33 | if (list == NULL || action == NULL) | ||
34 | return EINVAL; | ||
35 | status = mu_list_get_iterator (list, &itr); | ||
36 | if (status) | ||
37 | return status; | ||
38 | |||
39 | status = mu_iterator_ctl (itr, mu_itrctl_set_direction, &dir); | ||
40 | if (status == 0) | ||
41 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); | ||
42 | mu_iterator_next (itr)) | ||
43 | { | ||
44 | void *item; | ||
45 | mu_iterator_current (itr, &item); | ||
46 | if ((status = action (item, cbdata))) | ||
47 | break; | ||
48 | } | ||
49 | mu_iterator_destroy (&itr); | ||
50 | return status; | ||
51 | } | ||
52 |
... | @@ -29,7 +29,7 @@ mu_list_head (mu_list_t list, void **pitem) | ... | @@ -29,7 +29,7 @@ mu_list_head (mu_list_t list, void **pitem) |
29 | return EINVAL; | 29 | return EINVAL; |
30 | if (pitem == NULL) | 30 | if (pitem == NULL) |
31 | return MU_ERR_OUT_PTR_NULL; | 31 | return MU_ERR_OUT_PTR_NULL; |
32 | if (!list->head.next) | 32 | if (list->head.next == &list->head) |
33 | return MU_ERR_NOENT; | 33 | return MU_ERR_NOENT; |
34 | *pitem = list->head.next->item; | 34 | *pitem = list->head.next->item; |
35 | return 0; | 35 | return 0; | ... | ... |
... | @@ -29,7 +29,7 @@ mu_list_tail (mu_list_t list, void **pitem) | ... | @@ -29,7 +29,7 @@ mu_list_tail (mu_list_t list, void **pitem) |
29 | return EINVAL; | 29 | return EINVAL; |
30 | if (pitem == NULL) | 30 | if (pitem == NULL) |
31 | return MU_ERR_OUT_PTR_NULL; | 31 | return MU_ERR_OUT_PTR_NULL; |
32 | if (!list->head.prev) | 32 | if (list->head.prev == &list->head) |
33 | return MU_ERR_NOENT; | 33 | return MU_ERR_NOENT; |
34 | *pitem = list->head.prev->item; | 34 | *pitem = list->head.prev->item; |
35 | return 0; | 35 | return 0; | ... | ... |
... | @@ -24,8 +24,11 @@ libmsgset_la_SOURCES = \ | ... | @@ -24,8 +24,11 @@ libmsgset_la_SOURCES = \ |
24 | create.c\ | 24 | create.c\ |
25 | getitr.c\ | 25 | getitr.c\ |
26 | getlist.c\ | 26 | getlist.c\ |
27 | foreachnum.c\ | ||
28 | foreachmsg.c\ | ||
27 | free.c\ | 29 | free.c\ |
28 | locate.c\ | 30 | locate.c\ |
31 | negate.c\ | ||
29 | parse.c\ | 32 | parse.c\ |
30 | print.c\ | 33 | print.c\ |
31 | sub.c | 34 | sub.c | ... | ... |
libmailutils/msgset/foreachmsg.c
0 → 100644
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 | struct action_closure | ||
27 | { | ||
28 | mu_msgset_message_action_t action; | ||
29 | void *data; | ||
30 | mu_msgset_t msgset; | ||
31 | int dir; | ||
32 | }; | ||
33 | |||
34 | static int | ||
35 | procrange (void *item, void *data) | ||
36 | { | ||
37 | struct mu_msgrange *mp = item; | ||
38 | struct action_closure *clos = data; | ||
39 | size_t i; | ||
40 | |||
41 | if (clos->dir) | ||
42 | for (i = mp->msg_end; i >= mp->msg_beg; i--) | ||
43 | { | ||
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 | ||
60 | for (i = mp->msg_beg; i <= mp->msg_end; i++) | ||
61 | { | ||
62 | int 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 | } | ||
79 | |||
80 | /* Apply ACTION to each message number from MSGSET. */ | ||
81 | int | ||
82 | mu_msgset_foreach_dir_message (mu_msgset_t msgset, int dir, | ||
83 | mu_msgset_message_action_t action, | ||
84 | void *data) | ||
85 | { | ||
86 | int rc; | ||
87 | struct action_closure clos; | ||
88 | |||
89 | rc = mu_msgset_aggregate (msgset); | ||
90 | if (rc) | ||
91 | return rc; | ||
92 | clos.action = action; | ||
93 | clos.data = data; | ||
94 | clos.msgset = msgset; | ||
95 | clos.dir = dir; | ||
96 | return mu_list_foreach_dir (msgset->list, dir, procrange, &clos); | ||
97 | } | ||
98 | |||
99 | int | ||
100 | mu_msgset_foreach_message (mu_msgset_t msgset, | ||
101 | mu_msgset_message_action_t action, | ||
102 | void *data) | ||
103 | { | ||
104 | return mu_msgset_foreach_dir_message (msgset, 0, action, data); | ||
105 | } |
libmailutils/msgset/foreachnum.c
0 → 100644
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 action_closure | ||
26 | { | ||
27 | mu_msgset_msgno_action_t action; | ||
28 | void *data; | ||
29 | mu_msgset_t msgset; | ||
30 | int dir; | ||
31 | }; | ||
32 | |||
33 | static int | ||
34 | procrange (void *item, void *data) | ||
35 | { | ||
36 | struct mu_msgrange *mp = item; | ||
37 | struct action_closure *clos = data; | ||
38 | size_t i; | ||
39 | |||
40 | if (clos->dir) | ||
41 | for (i = mp->msg_end; i >= mp->msg_beg; i--) | ||
42 | { | ||
43 | int rc = clos->action (i, clos->data); | ||
44 | if (rc) | ||
45 | return rc; | ||
46 | } | ||
47 | else | ||
48 | for (i = mp->msg_beg; i <= mp->msg_end; i++) | ||
49 | { | ||
50 | int rc = clos->action (i, clos->data); | ||
51 | if (rc) | ||
52 | return rc; | ||
53 | } | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | /* Apply ACTION to each message number from MSGSET. */ | ||
58 | int | ||
59 | mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir, | ||
60 | mu_msgset_msgno_action_t action, | ||
61 | void *data) | ||
62 | { | ||
63 | int rc; | ||
64 | struct action_closure clos; | ||
65 | |||
66 | rc = mu_msgset_aggregate (msgset); | ||
67 | if (rc) | ||
68 | return rc; | ||
69 | clos.action = action; | ||
70 | clos.data = data; | ||
71 | clos.dir = dir; | ||
72 | return mu_list_foreach_dir (msgset->list, dir, procrange, &clos); | ||
73 | } | ||
74 | |||
75 | int | ||
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 | } |
... | @@ -24,7 +24,11 @@ | ... | @@ -24,7 +24,11 @@ |
24 | int | 24 | int |
25 | mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr) | 25 | mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr) |
26 | { | 26 | { |
27 | int rc; | ||
27 | if (!msgset) | 28 | if (!msgset) |
28 | return EINVAL; | 29 | return EINVAL; |
30 | rc = mu_msgset_aggregate (msgset); | ||
31 | if (rc) | ||
32 | return rc; | ||
29 | return mu_list_get_iterator (msgset->list, pitr); | 33 | return mu_list_get_iterator (msgset->list, pitr); |
30 | } | 34 | } | ... | ... |
... | @@ -24,10 +24,14 @@ | ... | @@ -24,10 +24,14 @@ |
24 | int | 24 | int |
25 | mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist) | 25 | mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist) |
26 | { | 26 | { |
27 | int rc; | ||
27 | if (!msgset) | 28 | if (!msgset) |
28 | return EINVAL; | 29 | return EINVAL; |
29 | if (!plist) | 30 | if (!plist) |
30 | return MU_ERR_OUT_PTR_NULL; | 31 | return MU_ERR_OUT_PTR_NULL; |
32 | rc = mu_msgset_aggregate (msgset); | ||
33 | if (rc) | ||
34 | return rc; | ||
31 | *plist = msgset->list; | 35 | *plist = msgset->list; |
32 | return 0; | 36 | return 0; |
33 | } | 37 | } | ... | ... |
... | @@ -26,7 +26,11 @@ int | ... | @@ -26,7 +26,11 @@ int |
26 | mu_msgset_locate (mu_msgset_t msgset, size_t n, | 26 | mu_msgset_locate (mu_msgset_t msgset, size_t n, |
27 | struct mu_msgrange const **prange) | 27 | struct mu_msgrange const **prange) |
28 | { | 28 | { |
29 | int rc; | ||
29 | if (!msgset || n == 0) | 30 | if (!msgset || n == 0) |
30 | return EINVAL; | 31 | return EINVAL; |
32 | rc = mu_msgset_aggregate (msgset); | ||
33 | if (rc) | ||
34 | return rc; | ||
31 | return mu_list_locate (msgset->list, &n, (void**)prange); | 35 | return mu_list_locate (msgset->list, &n, (void**)prange); |
32 | } | 36 | } | ... | ... |
libmailutils/msgset/negate.c
0 → 100644
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/mailbox.h> | ||
23 | #include <mailutils/msgset.h> | ||
24 | #include <mailutils/sys/msgset.h> | ||
25 | |||
26 | struct invert_closure | ||
27 | { | ||
28 | mu_msgset_t nset; | ||
29 | size_t next_num; | ||
30 | }; | ||
31 | |||
32 | static int | ||
33 | _invert_range (void *item, void *data) | ||
34 | { | ||
35 | struct mu_msgrange *range = item; | ||
36 | struct invert_closure *clos = data; | ||
37 | int rc; | ||
38 | |||
39 | if (clos->next_num < range->msg_beg - 1) | ||
40 | { | ||
41 | rc = mu_msgset_add_range (clos->nset, clos->next_num, range->msg_beg - 1); | ||
42 | if (rc) | ||
43 | return rc; | ||
44 | } | ||
45 | clos->next_num = range->msg_end + 1; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | /* Negate the message set: on return PNSET consists of the messages | ||
50 | _not contained_ in the input message set. */ | ||
51 | int | ||
52 | mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset) | ||
53 | { | ||
54 | int rc; | ||
55 | struct invert_closure clos; | ||
56 | size_t total; | ||
57 | |||
58 | if (!msgset) | ||
59 | return EINVAL; | ||
60 | if (!msgset->mbox) | ||
61 | return MU_ERR_NOT_OPEN; | ||
62 | |||
63 | rc = mu_msgset_aggregate (msgset); | ||
64 | if (rc) | ||
65 | return rc; | ||
66 | rc = mu_mailbox_messages_count (msgset->mbox, &total); | ||
67 | if (rc) | ||
68 | return rc; | ||
69 | rc = mu_msgset_create (&clos.nset, NULL, 0); | ||
70 | if (rc) | ||
71 | return rc; | ||
72 | clos.next_num = 1; | ||
73 | rc = mu_list_foreach (msgset->list, _invert_range, &clos); | ||
74 | if (rc == 0) | ||
75 | { | ||
76 | if (clos.next_num < total) | ||
77 | rc = mu_msgset_add_range (clos.nset, clos.next_num, total); | ||
78 | } | ||
79 | |||
80 | if (rc) | ||
81 | mu_msgset_free (clos.nset); | ||
82 | else | ||
83 | { | ||
84 | clos.nset->mbox = msgset->mbox; | ||
85 | *pnset = clos.nset; | ||
86 | } | ||
87 | return 0; | ||
88 | } |
... | @@ -101,14 +101,6 @@ parse_msgrange (struct parse_msgnum_env *env) | ... | @@ -101,14 +101,6 @@ parse_msgrange (struct parse_msgnum_env *env) |
101 | 101 | ||
102 | rc = mu_mailbox_translate (env->msgset->mbox, | 102 | rc = mu_mailbox_translate (env->msgset->mbox, |
103 | MU_MAILBOX_UID_TO_MSGNO, | 103 | MU_MAILBOX_UID_TO_MSGNO, |
104 | msgrange.msg_beg, &msgrange.msg_beg); | ||
105 | if (rc == MU_ERR_NOENT) | ||
106 | msgrange.msg_beg = env->minval; | ||
107 | else if (rc) | ||
108 | return rc; | ||
109 | |||
110 | rc = mu_mailbox_translate (env->msgset->mbox, | ||
111 | MU_MAILBOX_UID_TO_MSGNO, | ||
112 | msgrange.msg_end, &msgrange.msg_end); | 104 | msgrange.msg_end, &msgrange.msg_end); |
113 | if (rc == MU_ERR_NOENT) | 105 | if (rc == MU_ERR_NOENT) |
114 | msgrange.msg_end = env->maxval; | 106 | msgrange.msg_end = env->maxval; | ... | ... |
... | @@ -117,6 +117,13 @@ main (int argc, char **argv) | ... | @@ -117,6 +117,13 @@ main (int argc, char **argv) |
117 | MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg, | 117 | MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg, |
118 | range.msg_end)); | 118 | range.msg_end)); |
119 | } | 119 | } |
120 | else if (strcmp (arg, "-neg") == 0) | ||
121 | { | ||
122 | mu_msgset_t negated_set; | ||
123 | MU_ASSERT (mu_msgset_negate (msgset, &negated_set)); | ||
124 | mu_msgset_free (msgset); | ||
125 | msgset = negated_set; | ||
126 | } | ||
120 | else | 127 | else |
121 | { | 128 | { |
122 | mu_error ("unknown option %s", arg); | 129 | mu_error ("unknown option %s", arg); | ... | ... |
-
Please register or sign in to post a comment