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)
mu_mailbox_t cmbox = NULL;
int arg = IMAP4_ARG_1 + !!isuid;
int ns;
*err_text = NULL;
if (imap4d_tokbuf_argc (tok) != arg + 2)
{
......@@ -221,14 +221,16 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
msgset_str = imap4d_tokbuf_getarg (tok, arg);
name = imap4d_tokbuf_getarg (tok, arg + 1);
status = mu_msgset_create (&msgset, mbox, isuid ? MU_MSGSET_UID : 0);
status = mu_msgset_create (&msgset, mbox, MU_MSGSET_NUM);
if (!status)
{
*err_text = "Software error";
return RESP_BAD;
}
status = mu_msgset_parse_imap (msgset, msgset_str, &end);
status = mu_msgset_parse_imap (msgset,
isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
msgset_str, &end);
if (status)
{
mu_msgset_free (msgset);
......
......@@ -1759,13 +1759,14 @@ fetch_thunk (imap4d_parsebuf_t pb)
mstr = imap4d_parsebuf_next (pb, 1);
status = mu_msgset_create (&pclos->msgset, mbox,
pclos->isuid ? MU_MSGSET_UID : 0);
status = mu_msgset_create (&pclos->msgset, mbox, MU_MSGSET_NUM);
if (status)
imap4d_parsebuf_exit (pb, "Software error");
/* Parse sequence numbers. */
status = mu_msgset_parse_imap (pclos->msgset, mstr, &end);
status = mu_msgset_parse_imap (pclos->msgset,
pclos->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
mstr, &end);
if (status)
imap4d_parsebuf_exit (pb, "Failed to parse message set");
......
......@@ -608,10 +608,11 @@ parse_simple_key (struct parsebuf *pb)
if (!condp->name)
{
mu_msgset_t msgset = parse_msgset_create (pb, mbox,
pb->isuid ? MU_MSGSET_UID : 0);
mu_msgset_t msgset = parse_msgset_create (pb, mbox, MU_MSGSET_NUM);
if (mu_msgset_parse_imap (msgset, pb->token, NULL) == 0)
if (mu_msgset_parse_imap (msgset,
pb->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
pb->token, NULL) == 0)
{
struct search_node *np = parse_alloc (pb, sizeof *np);
np->type = node_value;
......@@ -696,9 +697,10 @@ parse_simple_key (struct parsebuf *pb)
break;
case 'u': /* UID message set */
arg->v.value.v.msgset = parse_msgset_create (pb, NULL, 0);
if (mu_msgset_parse_imap (arg->v.value.v.msgset, pb->token,
NULL))
arg->v.value.v.msgset = parse_msgset_create (pb, NULL,
MU_MSGSET_NUM);
if (mu_msgset_parse_imap (arg->v.value.v.msgset, MU_MSGSET_UID,
pb->token, NULL))
{
mu_msgset_free (arg->v.value.v.msgset);
pb->err_mesg = "Bogus number set";
......
......@@ -69,13 +69,14 @@ store_thunk (imap4d_parsebuf_t p)
imap4d_parsebuf_exit (p, "Bogus data suffix");
}
status = mu_msgset_create (&pclos->msgset, mbox,
pclos->isuid ? MU_MSGSET_UID : 0);
status = mu_msgset_create (&pclos->msgset, mbox, MU_MSGSET_NUM);
if (status)
imap4d_parsebuf_exit (p, "Software error");
/* Get the message numbers in set[]. */
status = mu_msgset_parse_imap (pclos->msgset, mstr, &end);
status = mu_msgset_parse_imap (pclos->msgset,
pclos->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
mstr, &end);
if (status)
imap4d_parsebuf_exit (p, "Failed to parse message set");
......
......@@ -18,6 +18,8 @@
#ifndef _MAILUTILS_MSGSET_H
#define _MAILUTILS_MSGSET_H
# include <mailutils/types.h>
#ifdef __cplusplus
extern "C" {
#endif
......@@ -31,23 +33,26 @@ struct mu_msgrange
/* Message numbers start with 1. MU_MSGNO_LAST denotes the last
message. */
#define MU_MSGNO_LAST 0
#define MU_MSGSET_UID 0x01 /* Message set operates on UIDs */
int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int flags);
#define MU_MSGSET_NUM 0 /* Message set operates on sequence numbers */
#define MU_MSGSET_UID 1 /* Message set operates on UIDs */
#define MU_MSGSET_MODE_MASK 0x0f
int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode);
int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist);
int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr);
int mu_msgset_add_range (mu_msgset_t list, size_t beg, size_t end);
int mu_msgset_sub_range (mu_msgset_t list, size_t beg, size_t end);
/*int mu_msgset_add_set (mu_msgset_t a, mu_msgset_t b);*/
/*int mu_msgset_sub_set (mu_msgset_t a, mu_msgset_t b);*/
int mu_msgset_add_range (mu_msgset_t set, size_t beg, size_t end, int mode);
int mu_msgset_sub_range (mu_msgset_t set, size_t beg, size_t end, int mode);
int mu_msgset_add (mu_msgset_t a, mu_msgset_t b);
int mu_msgset_sub (mu_msgset_t a, mu_msgset_t b);
int mu_msgset_aggregate (mu_msgset_t set);
int mu_msgset_clear (mu_msgset_t set);
void mu_msgset_free (mu_msgset_t set);
void mu_msgset_destroy (mu_msgset_t *set);
int mu_msgset_parse_imap (mu_msgset_t set, const char *s, char **end);
int mu_msgset_parse_imap (mu_msgset_t set, int mode, const char *s, char **end);
int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset);
......@@ -55,17 +60,34 @@ int mu_msgset_locate (mu_msgset_t msgset, size_t n,
struct mu_msgrange const **prange);
int mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset);
int mu_msgset_count (mu_msgset_t mset, size_t *pcount);
int mu_msgset_is_empty (mu_msgset_t mset);
typedef int (*mu_msgset_msgno_action_t) (size_t _n, void *_call_data);
typedef int (*mu_msgset_message_action_t) (size_t _n, mu_message_t _msg,
void *_call_data);
#define MU_MSGSET_FOREACH_FORWARD 0x00
#define MU_MSGSET_FOREACH_BACKWARD 0x10
int mu_msgset_foreach_num (mu_msgset_t _msgset, int _flags,
mu_msgset_msgno_action_t _action,
void *_call_data);
int mu_msgset_foreach_dir_msgno (mu_msgset_t _msgset, int _dir,
mu_msgset_msgno_action_t _action,
void *_data);
int mu_msgset_foreach_msgno (mu_msgset_t _msgset,
mu_msgset_msgno_action_t _action,
void *_call_data);
int mu_msgset_foreach_dir_msguid (mu_msgset_t _msgset, int _dir,
mu_msgset_msgno_action_t _action,
void *_data);
int mu_msgset_foreach_msguid (mu_msgset_t _msgset,
mu_msgset_msgno_action_t _action,
void *_data);
int mu_msgset_foreach_dir_message (mu_msgset_t _msgset, int _dir,
mu_msgset_message_action_t _action,
void *_call_data);
......
......@@ -28,4 +28,9 @@ struct _mu_msgset
int flags; /* Message set flags */
};
int _mu_msgset_translate_pair (mu_msgset_t mset, int mode,
size_t *beg, size_t *end);
int _mu_msgset_translate_range (mu_msgset_t mset, int mode,
struct mu_msgrange *r);
#endif
......
......@@ -19,19 +19,26 @@ noinst_LTLIBRARIES = libmsgset.la
libmsgset_la_SOURCES = \
add.c\
addset.c\
aggr.c\
clear.c\
create.c\
count.c\
getitr.c\
getlist.c\
foreachnum.c\
foreachmsgno.c\
foreachuid.c\
foreachmsg.c\
free.c\
isempty.c\
locate.c\
negate.c\
parse.c\
print.c\
sub.c
sub.c\
subset.c\
trans.c
INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
......@@ -23,18 +23,30 @@
#include <mailutils/sys/msgset.h>
int
mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end)
mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end, int mode)
{
int rc;
struct mu_msgrange *range;
if (!mset || beg == 0)
return EINVAL;
if (end && beg > end)
{
size_t t = end;
end = beg;
beg = t;
}
range = calloc (1, sizeof (*range));
if (!range)
return ENOMEM;
range->msg_beg = beg;
range->msg_end = end;
rc = _mu_msgset_translate_range (mset, mode, range);
if (rc)
{
free (range);
return rc;
}
rc = mu_list_append (mset->list, range);
if (rc)
free (range);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/msgset.h>
struct add_closure
{
int mode;
mu_msgset_t dest;
};
static int
add_range (void *item, void *data)
{
struct mu_msgrange *r = item;
struct add_closure *clos = data;
return mu_msgset_add_range (clos->dest, r->msg_beg, r->msg_end, clos->mode);
}
int
mu_msgset_add (mu_msgset_t a, mu_msgset_t b)
{
struct add_closure closure;
if (!a)
return EINVAL;
if (!b)
return 0;
closure.mode = b->flags;
closure.dest = a;
return mu_list_foreach (b->list, add_range, &closure);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/msgset.h>
static int
count_messages (void *item, void *data)
{
struct mu_msgrange *r = item;
size_t *count = data;
*count += r->msg_end - r->msg_beg + 1;
return 0;
}
int
mu_msgset_count (mu_msgset_t mset, size_t *pcount)
{
int rc;
size_t count = 0;
if (!mset)
return EINVAL;
if (!pcount)
return MU_ERR_OUT_PTR_NULL;
rc = mu_list_foreach (mset->list, count_messages, &count);
if (rc == 0)
*pcount = count;
return rc;
}
......@@ -32,49 +32,47 @@ struct action_closure
};
static int
call_action (struct action_closure *clos, size_t i)
{
int rc;
mu_message_t msg = NULL;
size_t n;
if (clos->msgset->flags == MU_MSGSET_UID)
{
rc = mu_mailbox_translate (clos->msgset->mbox, MU_MAILBOX_UID_TO_MSGNO,
i, &n);
if (rc == MU_ERR_NOENT)
return 0;
else if (rc)
return rc;
}
else
n = i;
rc = mu_mailbox_get_message (clos->msgset->mbox, n, &msg);
if (rc == MU_ERR_NOENT)
return 0;
else if (rc == 0)
rc = clos->action (i, msg, clos->data);
return rc;
}
static int
procrange (void *item, void *data)
{
struct mu_msgrange *mp = item;
struct action_closure *clos = data;
size_t i;
int rc = 0;
if (clos->dir)
for (i = mp->msg_end; i >= mp->msg_beg; i--)
{
int rc;
mu_message_t msg = NULL;
if (clos->msgset->mbox)
{
rc = mu_mailbox_get_message (clos->msgset->mbox, i, &msg);
if (rc == MU_ERR_NOENT)
continue;
else if (rc)
return rc;
}
rc = clos->action (i, msg, clos->data);
if (rc)
return rc;
}
for (i = mp->msg_end; rc == 0 && i >= mp->msg_beg; i--)
rc = call_action (clos, i);
else
for (i = mp->msg_beg; i <= mp->msg_end; i++)
{
int rc;
mu_message_t msg = NULL;
if (clos->msgset->mbox)
{
rc = mu_mailbox_get_message (clos->msgset->mbox, i, &msg);
if (rc == MU_ERR_NOENT)
continue;
else if (rc)
return rc;
}
rc = clos->action (i, msg, clos->data);
if (rc)
return rc;
}
return 0;
rc = call_action (clos, i);
return rc;
}
/* Apply ACTION to each message number from MSGSET. */
......@@ -85,7 +83,9 @@ mu_msgset_foreach_dir_message (mu_msgset_t msgset, int dir,
{
int rc;
struct action_closure clos;
if (!msgset->mbox)
return MU_ERR_NOT_OPEN;
rc = mu_msgset_aggregate (msgset);
if (rc)
return rc;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <mailutils/msgset.h>
/* Apply ACTION to each message number from MSGSET. */
int
mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
mu_msgset_msgno_action_t action,
void *data)
{
return mu_msgset_foreach_num (msgset,
(dir ? MU_MSGSET_FOREACH_BACKWARD : MU_MSGSET_FOREACH_FORWARD)|
MU_MSGSET_NUM,
action, data);
}
int
mu_msgset_foreach_msgno (mu_msgset_t msgset,
mu_msgset_msgno_action_t action,
void *data)
{
return mu_msgset_foreach_dir_msgno (msgset, 0, action, data);
}
......@@ -20,6 +20,7 @@
#include <mailutils/errno.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
#include <mailutils/mailbox.h>
#include <mailutils/sys/msgset.h>
struct action_closure
......@@ -27,38 +28,67 @@ struct action_closure
mu_msgset_msgno_action_t action;
void *data;
mu_msgset_t msgset;
int dir;
int flags;
};
static int
call_action (struct action_closure *clos, size_t i)
{
size_t n;
int cmd;
if (clos->msgset->flags != (clos->flags & MU_MSGSET_MODE_MASK))
{
int rc;
switch (clos->flags & MU_MSGSET_MODE_MASK)
{
case MU_MSGSET_NUM:
cmd = MU_MAILBOX_UID_TO_MSGNO;
break;
case MU_MSGSET_UID:
cmd = MU_MAILBOX_MSGNO_TO_UID;
break;
default:
return EINVAL;
}
rc = mu_mailbox_translate (clos->msgset->mbox, cmd, i, &n);
if (rc == MU_ERR_NOENT)
return 0;
if (rc)
return rc;
}
else
n = i;
return clos->action (n, clos->data);
}
static int
procrange (void *item, void *data)
{
struct mu_msgrange *mp = item;
struct action_closure *clos = data;
size_t i;
if (clos->dir)
for (i = mp->msg_end; i >= mp->msg_beg; i--)
{
int rc = clos->action (i, clos->data);
if (rc)
return rc;
}
int rc = 0;
if (clos->flags & MU_MSGSET_FOREACH_BACKWARD)
for (i = mp->msg_end; rc == 0 && i >= mp->msg_beg; i--)
rc = call_action (clos, i);
else
for (i = mp->msg_beg; i <= mp->msg_end; i++)
{
int rc = clos->action (i, clos->data);
if (rc)
return rc;
}
return 0;
for (i = mp->msg_beg; rc == 0 && i <= mp->msg_end; i++)
rc = call_action (clos, i);
return rc;
}
/* Apply ACTION to each message number from MSGSET. */
/* Apply ACTION to each message number or UID from MSGSET. */
int
mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
mu_msgset_msgno_action_t action,
void *data)
mu_msgset_foreach_num (mu_msgset_t msgset, int flags,
mu_msgset_msgno_action_t action,
void *data)
{
int rc;
struct action_closure clos;
......@@ -68,14 +98,9 @@ mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
return rc;
clos.action = action;
clos.data = data;
clos.dir = dir;
return mu_list_foreach_dir (msgset->list, dir, procrange, &clos);
}
int
mu_msgset_foreach_msgno (mu_msgset_t msgset,
mu_msgset_msgno_action_t action,
void *data)
{
return mu_msgset_foreach_dir_msgno (msgset, 0, action, data);
clos.flags = flags;
clos.msgset = msgset;
return mu_list_foreach_dir (msgset->list,
!!(flags & MU_MSGSET_FOREACH_BACKWARD),
procrange, &clos);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <mailutils/msgset.h>
/* Apply ACTION to each message number from MSGSET. */
int
mu_msgset_foreach_dir_msguid (mu_msgset_t msgset, int dir,
mu_msgset_msgno_action_t action,
void *data)
{
return mu_msgset_foreach_num (msgset,
(dir ? MU_MSGSET_FOREACH_BACKWARD : MU_MSGSET_FOREACH_FORWARD) |
MU_MSGSET_UID, action, data);
}
int
mu_msgset_foreach_msguid (mu_msgset_t msgset,
mu_msgset_msgno_action_t action,
void *data)
{
return mu_msgset_foreach_dir_msguid (msgset, 0, action, data);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/msgset.h>
int
mu_msgset_is_empty (mu_msgset_t mset)
{
return mset == NULL || mu_list_is_empty (mset->list);
}
......@@ -38,7 +38,9 @@ _invert_range (void *item, void *data)
if (clos->next_num < range->msg_beg - 1)
{
rc = mu_msgset_add_range (clos->nset, clos->next_num, range->msg_beg - 1);
rc = mu_msgset_add_range (clos->nset,
clos->next_num, range->msg_beg - 1,
clos->nset->flags);
if (rc)
return rc;
}
......@@ -66,7 +68,15 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
rc = mu_mailbox_messages_count (msgset->mbox, &total);
if (rc)
return rc;
rc = mu_msgset_create (&clos.nset, NULL, 0);
if (msgset->flags == MU_MSGSET_UID)
{
rc = mu_mailbox_translate (msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
total, &total);
if (rc)
return rc;
}
rc = mu_msgset_create (&clos.nset, msgset->mbox, msgset->flags);
if (rc)
return rc;
clos.next_num = 1;
......@@ -74,15 +84,14 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
if (rc == 0)
{
if (clos.next_num < total)
rc = mu_msgset_add_range (clos.nset, clos.next_num, total);
rc = mu_msgset_add_range (clos.nset, clos.next_num, total,
clos.nset->flags);
}
if (rc)
mu_msgset_free (clos.nset);
else
{
clos.nset->mbox = msgset->mbox;
*pnset = clos.nset;
}
return 0;
*pnset = clos.nset;
return rc;
}
......
......@@ -33,6 +33,7 @@ struct parse_msgnum_env
size_t minval; /* Min. sequence number or UID */
size_t maxval; /* Max. sequence number or UID */
mu_msgset_t msgset; /* Message set being built. */
int mode; /* Operation mode (num/uid) */
};
/* 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)
msgrange.msg_beg = tmp;
}
if ((env->msgset->flags & MU_MSGSET_UID) && env->msgset->mbox)
{
int rc;
rc = mu_mailbox_translate (env->msgset->mbox,
MU_MAILBOX_UID_TO_MSGNO,
msgrange.msg_end, &msgrange.msg_end);
if (rc == MU_ERR_NOENT)
msgrange.msg_end = env->maxval;
else if (rc)
return rc;
}
return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end);
return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end,
env->mode);
}
/* Parse IMAP-style message set specification S.
......@@ -117,13 +106,15 @@ parse_msgrange (struct parse_msgnum_env *env)
On error, return error code and point END to the position in the input
string where parsing has failed. */
int
mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end)
mu_msgset_parse_imap (mu_msgset_t mset, int mode, const char *s, char **end)
{
int rc;
struct parse_msgnum_env env;
if (!s || !mset)
return EINVAL;
if (end)
*end = (char*) s;
if (!*s)
return MU_ERR_PARSE;
......@@ -131,9 +122,8 @@ mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end)
env.s = s;
env.msgset = mset;
env.minval = 1;
env.mode = mode;
if (end)
*end = (char*) s;
if (mset->mbox)
{
size_t lastmsgno; /* Max. sequence number. */
......@@ -141,7 +131,7 @@ mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end)
rc = mu_mailbox_messages_count (mset->mbox, &lastmsgno);
if (rc == 0)
{
if (mset->flags & MU_MSGSET_UID)
if (mode == MU_MSGSET_UID)
{
rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID,
lastmsgno, &env.maxval);
......
......@@ -112,7 +112,7 @@ sub_msgno_last (mu_msgset_t mset, size_t beg)
}
int
mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end, int mode)
{
int rc;
mu_iterator_t itr;
......@@ -122,6 +122,19 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
return EINVAL;
if (mu_list_is_empty (mset->list))
return MU_ERR_NOENT;
if (end && beg > end)
{
size_t t = end;
end = beg;
beg = t;
}
rc = _mu_msgset_translate_pair (mset, mode, &beg, &end);
if (rc == MU_ERR_NOENT)
return 0;
else if (rc)
return rc;
rc = mu_msgset_aggregate (mset);
if (rc)
return rc;
......@@ -138,8 +151,6 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
if (beg < mr->msg_beg)
beg = mr->msg_beg;
if (rc)
return rc;
rc = mu_list_tail (mset->list, (void**) &mr);
if (mr->msg_end != MU_MSGNO_LAST)
{
......@@ -148,7 +159,7 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
if (end > mr->msg_end)
end = mr->msg_end;
}
rc = mu_list_get_iterator (mset->list, &itr);
if (rc)
return rc;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/msgset.h>
struct sub_closure
{
int mode;
mu_msgset_t dest;
};
static int
sub_range (void *item, void *data)
{
struct mu_msgrange *r = item;
struct sub_closure *clos = data;
return mu_msgset_sub_range (clos->dest, r->msg_beg, r->msg_end, clos->mode);
}
int
mu_msgset_sub (mu_msgset_t a, mu_msgset_t b)
{
struct sub_closure closure;
if (!a)
return EINVAL;
if (!b)
return 0;
closure.mode = b->flags;
closure.dest = a;
return mu_list_foreach (b->list, sub_range, &closure);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
#include <mailutils/mailbox.h>
#include <mailutils/sys/msgset.h>
int
_mu_msgset_translate_pair (mu_msgset_t mset, int mode,
size_t *pbeg, size_t *pend)
{
if (mode != mset->flags && mset->mbox)
{
int cmd, rc;
size_t n;
size_t beg = *pbeg;
size_t end = *pend;
switch (mset->flags)
{
case MU_MSGSET_NUM:
cmd = MU_MAILBOX_UID_TO_MSGNO;
break;
case MU_MSGSET_UID:
cmd = MU_MAILBOX_MSGNO_TO_UID;
break;
default:
return EINVAL;
}
rc = mu_mailbox_translate (mset->mbox, cmd, beg, &n);
if (rc)
{
if (rc == MU_ERR_NOENT && cmd == MU_MAILBOX_UID_TO_MSGNO)
{
size_t x;
if (end == MU_MSGNO_LAST)
{
rc = mu_mailbox_uidnext (mset->mbox, &x);
if (rc)
return rc;
}
else
x = end;
for (; rc == MU_ERR_NOENT && beg < x; beg++)
rc = mu_mailbox_translate (mset->mbox, cmd, beg, &n);
}
if (rc)
return rc;
}
*pbeg = n;
if (beg == end)
*pend = n;
else if (end != MU_MSGNO_LAST)
{
rc = mu_mailbox_translate (mset->mbox, cmd, end, &n);
if (rc == MU_ERR_NOENT && cmd == MU_MAILBOX_UID_TO_MSGNO)
{
for (; rc == MU_ERR_NOENT && beg < end; end--)
rc = mu_mailbox_translate (mset->mbox, cmd, end, &n);
}
if (rc)
return rc;
*pend = n;
}
}
return 0;
}
int
_mu_msgset_translate_range (mu_msgset_t mset, int mode, struct mu_msgrange *r)
{
return _mu_msgset_translate_pair (mset, mode, &r->msg_beg, &r->msg_end);
}
......@@ -19,7 +19,7 @@
#include <mailutils/mailutils.h>
static void
parse_msgset (char *arg, struct mu_msgrange *range)
parse_msgrange (char *arg, struct mu_msgrange *range)
{
size_t msgnum;
char *p;
......@@ -52,13 +52,33 @@ parse_msgset (char *arg, struct mu_msgrange *range)
range->msg_end = msgnum;
}
mu_msgset_t
parse_msgset (const char *arg)
{
int rc;
mu_msgset_t msgset;
char *end;
MU_ASSERT (mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM));
if (arg)
{
rc = mu_msgset_parse_imap (msgset, MU_MSGSET_NUM, arg, &end);
if (rc)
{
mu_error ("mu_msgset_parse_imap: %s near %s",
mu_strerror (rc), end);
exit (1);
}
}
return msgset;
}
int
main (int argc, char **argv)
{
int i;
char *msgset_string = NULL;
mu_msgset_t msgset;
int rc;
mu_set_program_name (argv[0]);
for (i = 1; i < argc; i++)
......@@ -67,7 +87,8 @@ main (int argc, char **argv)
if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
{
mu_printf ("usage: %s [-msgset=SET] [-add X[:Y]] [-del X:[Y]]...\n",
mu_printf ("usage: %s [-msgset=SET] [-add=X[:Y]] [-del=X[:Y]] "
"[-addset=SET] [-delset=SET] ...\n",
mu_program_name);
return 0;
}
......@@ -77,18 +98,7 @@ main (int argc, char **argv)
break;
}
MU_ASSERT (mu_msgset_create (&msgset, NULL, 0));
if (msgset_string)
{
char *end;
rc = mu_msgset_parse_imap (msgset, msgset_string, &end);
if (rc)
{
mu_error ("mu_msgset_parse_imap: %s near %s",
mu_strerror (rc), end);
return 1;
}
}
msgset = parse_msgset (msgset_string);
for (; i < argc; i++)
{
......@@ -97,15 +107,40 @@ main (int argc, char **argv)
if (strncmp (arg, "-add=", 5) == 0)
{
parse_msgset (arg + 5, &range);
parse_msgrange (arg + 5, &range);
MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg,
range.msg_end));
range.msg_end, MU_MSGSET_NUM));
}
else if (strncmp (arg, "-sub=", 5) == 0)
{
parse_msgset (arg + 5, &range);
parse_msgrange (arg + 5, &range);
MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg,
range.msg_end));
range.msg_end, MU_MSGSET_NUM));
}
else if (strncmp (arg, "-addset=", 8) == 0)
{
mu_msgset_t tset = parse_msgset (arg + 8);
if (!msgset)
msgset = tset;
else
{
MU_ASSERT (mu_msgset_add (msgset, tset));
mu_msgset_free (tset);
}
}
else if (strncmp (arg, "-subset=", 8) == 0)
{
mu_msgset_t tset = parse_msgset (arg + 8);
if (!msgset)
{
mu_error ("no initial message set");
exit (1);
}
else
{
MU_ASSERT (mu_msgset_sub (msgset, tset));
mu_msgset_free (tset);
}
}
else
{
......
......@@ -175,7 +175,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
if (rc)
return rc;
rc = mu_msgset_create (&msgset, NULL, 0);
rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
if (rc == 0)
{
struct save_closure clos;
......@@ -183,7 +183,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
clos.imsg = imsg;
clos.save_stream = imbx->cache;
rc = mu_msgset_add_range (msgset, msgno, msgno);
rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
if (rc == 0)
{
_imap_mbx_clrerr (imbx);
......@@ -370,10 +370,10 @@ _imap_hdr_fill (void *data, char **pbuf, size_t *plen)
unsigned long msgno = _imap_msg_no (imsg);
int rc;
rc = mu_msgset_create (&msgset, NULL, 0);
rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
if (rc == 0)
{
rc = mu_msgset_add_range (msgset, msgno, msgno);
rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
if (rc == 0)
{
clos.imsg = imsg;
......@@ -619,11 +619,11 @@ _imap_msg_bodystructure (mu_message_t msg, struct mu_bodystructure **pbs)
int rc;
mu_msgset_t msgset;
rc = mu_msgset_create (&msgset, NULL, 0);
rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
if (rc == 0)
{
size_t msgno = _imap_msg_no (imsg);
rc = mu_msgset_add_range (msgset, msgno, msgno);
rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
if (rc == 0)
rc = _imap_fetch_with_callback (imap, msgset, "BODYSTRUCTURE",
_imap_bodystructure_callback, pbs);
......@@ -949,7 +949,7 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
struct attr_tab *tab;
size_t count;
rc = mu_msgset_create (&msgset, NULL, 0);
rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
if (rc)
return rc;
......@@ -962,7 +962,7 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
{
mu_msgset_clear (msgset);
mu_msgset_add_range (msgset, i + 1, i + 1);
mu_msgset_add_range (msgset, i + 1, i + 1, MU_MSGSET_NUM);
if (rc)
break;
rc = mu_imap_store_flags (imap, 0, msgset,
......@@ -994,12 +994,13 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
}
}
if (tab[i].end == tab[i].start)
rc = mu_msgset_add_range (msgset, tab[i].start + 1,
tab[i].start + 1);
rc = mu_msgset_add_range (msgset,
tab[i].start + 1, tab[i].start + 1,
MU_MSGSET_NUM);
else
rc = mu_msgset_add_range (msgset,
tab[i].start + 1,
tab[i].end + 1);
tab[i].start + 1, tab[i].end + 1,
MU_MSGSET_NUM);
if (rc)
break;
}
......@@ -1192,10 +1193,10 @@ _imap_mbx_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("scanning mailbox %s"), mu_url_to_string (mbox->url)));
rc = mu_msgset_create (&msgset, NULL, 0);
rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
if (rc)
return rc;
rc = mu_msgset_add_range (msgset, msgno, MU_MSGNO_LAST);
rc = mu_msgset_add_range (msgset, msgno, MU_MSGNO_LAST, MU_MSGSET_NUM);
if (rc)
{
mu_msgset_free (msgset);
......
......@@ -95,10 +95,11 @@ opt_handler (int key, char *arg, struct argp_state *state)
return 0;
}
void
anno (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
anno (size_t n, mu_message_t msg, void *call_data)
{
mh_annotate (msg, component, anno_text, anno_date);
return 0;
}
int
......@@ -107,7 +108,7 @@ main (int argc, char **argv)
int rc;
int index;
mu_mailbox_t mbox;
mh_msgset_t msgset;
mu_msgset_t msgset;
size_t len;
MU_APP_INIT_NLS ();
......@@ -154,10 +155,16 @@ main (int argc, char **argv)
argc -= index;
argv += index;
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
rc = mh_iterate (mbox, &msgset, anno, NULL);
mh_msgset_current (mbox, &msgset, 0);
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
rc = mu_msgset_foreach_message (msgset, anno, NULL);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_foreach_message", NULL, rc);
exit (1);
}
mh_msgset_first_current (mbox, msgset);
mu_msgset_free (msgset);
mh_global_save_state ();
mu_mailbox_sync (mbox);
mu_mailbox_close (mbox);
......
......@@ -578,8 +578,8 @@ burst_or_copy (mu_message_t msg, int recursive, int copy)
return 1;
}
void
burst (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
burst (size_t num, mu_message_t msg, void *data)
{
memset (&map, 0, sizeof (map));
mh_message_number (msg, &map.msgno);
......@@ -599,36 +599,38 @@ burst (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
}
else if (!quiet)
mu_error (_("message %s not in digest format"), mu_umaxtostr (0, num));
return 0;
}
/* Inplace handling */
struct rename_env
{
size_t lastuid;
size_t idx;
};
void
burst_rename (mh_msgset_t *ms, size_t lastuid)
static int
_rename (size_t msgno, void *data)
{
size_t i, j;
struct rename_env *rp = data;
if (msgno == burst_map[rp->idx].msgno)
{
rp->lastuid -= burst_map[rp->idx].count;
burst_map[rp->idx].msgno = rp->lastuid;
rp->idx--;
}
VERBOSE ((_("Renaming messages")));
j = burst_count - 1;
for (i = ms->count; i > 0; i--)
if (msgno != rp->lastuid)
{
const char *from;
const char *to;
if (ms->list[i-1] == burst_map[j].msgno)
{
lastuid -= burst_map[j].count;
burst_map[j].msgno = lastuid;
j--;
}
if (ms->list[i-1] == lastuid)
continue;
from = mu_umaxtostr (0, ms->list[i-1]);
to = mu_umaxtostr (1, lastuid);
--lastuid;
from = mu_umaxtostr (0, msgno);
to = mu_umaxtostr (1, rp->lastuid);
--rp->lastuid;
VERBOSE((_("message %s becomes message %s"), from, to));
......@@ -639,6 +641,18 @@ burst_rename (mh_msgset_t *ms, size_t lastuid)
exit (1);
}
}
return 0;
}
void
burst_rename (mu_msgset_t ms, size_t lastuid)
{
struct rename_env renv;
VERBOSE ((_("Renaming messages")));
renv.lastuid = lastuid;
renv.idx = burst_count - 1;
mu_msgset_foreach_dir_msguid (ms, 1, _rename, &renv);
}
void
......@@ -705,7 +719,7 @@ main (int argc, char **argv)
{
int index, rc;
mu_mailbox_t mbox;
mh_msgset_t msgset;
mu_msgset_t msgset;
const char *tempfolder = mh_global_profile_get ("Temp-Folder", ".temp");
/* Native Language Support */
......@@ -720,7 +734,7 @@ main (int argc, char **argv)
VERBOSE ((_("Opening folder `%s'"), mh_current_folder ()));
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
if (inplace)
{
......@@ -744,7 +758,7 @@ main (int argc, char **argv)
else
tmpbox = mbox;
rc = mh_iterate (mbox, &msgset, burst, NULL);
rc = mu_msgset_foreach_message (msgset, burst, NULL);
if (rc)
return rc;
......@@ -752,8 +766,8 @@ main (int argc, char **argv)
{
mu_url_t dst_url = NULL;
size_t i, next_uid, last_uid;
mh_msgset_t ms;
char *xargv[2];
mu_msgset_t ms;
size_t count;
const char *dir;
burst_map = obstack_finish (&stk);
......@@ -763,11 +777,14 @@ main (int argc, char **argv)
last_uid += burst_map[i].count;
VERBOSE ((_("Estimated last UID: %s"), mu_umaxtostr (0, last_uid)));
mu_asprintf (&xargv[0], "%s-last", mu_umaxtostr (0, burst_map[0].msgno));
xargv[1] = NULL;
mh_msgset_parse (mbox, &ms, 1, xargv, NULL);
free (xargv[0]);
mh_msgset_uids (mbox, &ms);
rc = mu_msgset_create (&ms, mbox, MU_MSGSET_NUM);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc);
exit (1);
}
mu_mailbox_messages_count (mbox, &count);
mu_msgset_add_range (ms, burst_map[0].msgno, count, MU_MSGSET_NUM);
mu_mailbox_get_url (mbox, &dst_url);
mu_url_sget_path (dst_url, &dir);
......@@ -779,8 +796,8 @@ main (int argc, char **argv)
}
mu_mailbox_close (mbox);
burst_rename (&ms, last_uid);
mh_msgset_free (&ms);
burst_rename (ms, last_uid);
mu_msgset_free (ms);
finalize_inplace (last_uid);
......
......@@ -246,22 +246,21 @@ main (int argc, char **argv)
`-draftfolder +folder' treat this arguments as `msg'. */
if (use_draft || index < argc)
{
mh_msgset_t msgset;
mu_msgset_t msgset;
mu_mailbox_t mbox;
mbox = mh_open_folder (draftfolder,
MU_STREAM_RDWR|MU_STREAM_CREAT);
mh_msgset_parse (mbox, &msgset,
mh_msgset_parse (&msgset, mbox,
argc - index, argv + index,
use_draft ? "cur" : "new");
mh_msgset_uids (mbox, &msgset);
if (msgset.count != 1)
if (!mh_msgset_single_message (msgset))
{
mu_error (_("only one message at a time!"));
return 1;
}
draftmessage = mu_umaxtostr (0, msgset.list[0]);
mh_msgset_free (&msgset);
draftmessage = mu_umaxtostr (0, mh_msgset_first_uid (msgset));
mu_msgset_free (msgset);
mu_mailbox_destroy (&mbox);
}
if (mh_draft_message (draftfolder, draftmessage,
......@@ -273,20 +272,20 @@ main (int argc, char **argv)
if (folder_set && index < argc)
{
mh_msgset_t msgset;
mu_msgset_t msgset;
mu_mailbox_t mbox;
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur");
if (msgset.count != 1)
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
if (!mh_msgset_single_message (msgset))
{
mu_error (_("only one message at a time!"));
return 1;
}
unlink (wh_env.file);
copy_message (mbox, msgset.list[0], wh_env.file);
copy_message (mbox, mh_msgset_first (msgset), wh_env.file);
mu_mailbox_destroy (&mbox);
mh_msgset_free (&msgset);
mu_msgset_free (msgset);
}
else
{
......
......@@ -773,9 +773,10 @@ pack_xlate (struct pack_tab *pack_tab, size_t count, size_t n)
static int
_fixup (const char *name, const char *value, struct fixup_data *fd, int flags)
{
size_t i, j;
size_t i;
int rc;
struct mu_wordsplit ws;
mh_msgset_t msgset;
mu_msgset_t msgset;
if (verbose)
fprintf (stderr, "Sequence `%s'...\n", name);
......@@ -787,20 +788,32 @@ _fixup (const char *name, const char *value, struct fixup_data *fd, int flags)
return 0;
}
msgset.list = xcalloc (ws.ws_wordc, sizeof msgset.list[0]);
for (i = j = 0; i < ws.ws_wordc; i++)
rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_UID);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc);
exit (1);
}
for (i = 0; i < ws.ws_wordc; i++)
{
size_t n = pack_xlate (fd->pack_tab, fd->count,
strtoul (ws.ws_wordv[i], NULL, 0));
if (n)
msgset.list[j++] = n;
{
rc = mu_msgset_add_range (msgset, n, n, MU_MSGSET_UID);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_add_range", NULL, rc);
exit (1);
}
}
}
msgset.count = j;
mu_wordsplit_free (&ws);
mh_seq_add (fd->mbox, name, &msgset, flags | SEQ_ZERO);
free (msgset.list);
mh_seq_add (fd->mbox, name, msgset, flags | SEQ_ZERO);
mu_msgset_free (msgset);
if (verbose)
{
......@@ -944,7 +957,7 @@ int
main (int argc, char **argv)
{
int index = 0;
mh_msgset_t msgset;
mu_msgset_t msgset;
/* Native Language Support */
MU_APP_INIT_NLS ();
......@@ -971,9 +984,11 @@ main (int argc, char **argv)
if (argc - index == 1)
{
mu_mailbox_t mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur");
mh_msgset_current (mbox, &msgset, 0);
mu_mailbox_t mbox = mh_open_folder (mh_current_folder (),
MU_STREAM_RDWR);
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
mh_msgset_first_current (mbox, msgset);
mu_msgset_free (msgset);
mh_global_save_state ();
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
......
......@@ -116,7 +116,7 @@ static char *draftmessage = "new";
static const char *draftfolder = NULL;
static char *input_file; /* input file name (--file option) */
static mh_msgset_t msgset;
static mu_msgset_t msgset;
static mu_mailbox_t mbox;
static int
......@@ -331,15 +331,27 @@ format_message (mu_stream_t outstr, mu_message_t msg, int num,
}
}
void
format_message_itr (mu_mailbox_t mbox MU_ARG_UNUSED,
mu_message_t msg, size_t num, void *data)
int
format_message_itr (size_t num, mu_message_t msg, void *data)
{
struct format_data *fp = data;
format_message (fp->stream, msg, fp->num, fp->format);
if (fp->num)
fp->num++;
return 0;
}
static int
_proc_forwards (size_t n, mu_message_t msg, void *call_data)
{
mu_stream_t stream = call_data;
size_t num;
if (annotate)
mu_list_append (wh_env.anno_list, msg);
mh_message_number (msg, &num);
return mu_stream_printf (stream, " %lu", (unsigned long) num);
}
void
......@@ -411,36 +423,22 @@ finish_draft ()
{
mu_url_t url;
const char *mbox_path;
const char *p;
size_t i;
mu_mailbox_get_url (mbox, &url);
mu_url_sget_path (url, &mbox_path);
mu_asprintf (&str, "#forw [] +%s", mbox_path);
rc = mu_stream_write (stream, str, strlen (str), NULL);
free (str);
for (i = 0; rc == 0 && i < msgset.count; i++)
{
mu_message_t msg;
size_t num;
mu_mailbox_get_message (mbox, msgset.list[i], &msg);
if (annotate)
mu_list_append (wh_env.anno_list, msg);
mh_message_number (msg, &num);
p = mu_umaxtostr (0, num);
rc = mu_stream_write (stream, " ", 1, NULL);
if (rc)
break;
rc = mu_stream_write (stream, p, strlen (p), NULL);
}
mu_msgset_foreach_message (msgset, _proc_forwards, stream);
}
else
{
int single_message = mh_msgset_single_message (msgset);
str = "\n------- ";
rc = mu_stream_write (stream, str, strlen (str), NULL);
if (msgset.count == 1)
if (single_message)
{
fd.num = 0;
str = (char*) _("Forwarded message\n");
......@@ -454,12 +452,12 @@ finish_draft ()
rc = mu_stream_write (stream, str, strlen (str), NULL);
fd.stream = stream;
fd.format = format;
rc = mh_iterate (mbox, &msgset, format_message_itr, &fd);
rc = mu_msgset_foreach_message (msgset, format_message_itr, &fd);
str = "\n------- ";
rc = mu_stream_write (stream, str, strlen (str), NULL);
if (msgset.count == 1)
if (single_message)
str = (char*) _("End of Forwarded message");
else
str = (char*) _("End of Forwarded messages");
......@@ -504,7 +502,7 @@ main (int argc, char **argv)
else
{
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
}
if (build_only || !draftfolder)
......
......@@ -121,7 +121,7 @@ opt_handler (int key, char *arg, struct argp_state *state)
struct mark_closure
{
mu_mailbox_t mbox;
mh_msgset_t *msgset;
mu_msgset_t msgset;
};
static int
......@@ -191,7 +191,7 @@ int
main (int argc, char **argv)
{
int index;
mh_msgset_t msgset;
mu_msgset_t msgset;
mu_mailbox_t mbox;
mu_url_t url;
struct mark_closure clos;
......@@ -209,11 +209,11 @@ main (int argc, char **argv)
argc -= index;
argv += index;
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
mh_msgset_uids (mbox, &msgset);
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
clos.mbox = mbox;
clos.msgset = &msgset;
clos.msgset = msgset;
//FIXME: msgset operates on UIDs but there's no way to inform it about that.
switch (action)
{
case ARG_ADD:
......
......@@ -60,6 +60,7 @@
#include <mailutils/mh.h>
#include <mailutils/stdstream.h>
#include <mailutils/datetime.h>
#include <mailutils/msgset.h>
#include <mu_umaxtostr.h>
......@@ -194,19 +195,6 @@ typedef struct
mu_header_t header;
} mh_context_t;
#define MH_MSGSET_UID 0x01
typedef struct
{
int flags;
size_t *list;
size_t count;
size_t size;
} mh_msgset_t;
typedef void (*mh_iterator_fp) (mu_mailbox_t mbox, mu_message_t msg,
size_t num, void *data);
/* Recipient masks */
#define RCPT_NONE 0
#define RCPT_TO 0x0001
......@@ -303,14 +291,14 @@ int mh_message_number (mu_message_t msg, size_t *pnum);
mu_mailbox_t mh_open_folder (const char *folder, int flags);
void mh_msgset_parse (mu_mailbox_t mbox, mh_msgset_t *msgset,
void mh_msgset_parse (mu_msgset_t *msgset, mu_mailbox_t mbox,
int argc, char **argv, char *def);
int mh_msgset_member (mh_msgset_t *msgset, size_t num);
void mh_msgset_reverse (mh_msgset_t *msgset);
void mh_msgset_negate (mu_mailbox_t mbox, mh_msgset_t *msgset);
void mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index);
void mh_msgset_free (mh_msgset_t *msgset);
void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset);
void mh_msgset_parse_string (mu_msgset_t *msgset, mu_mailbox_t mbox,
const char *string, char *def);
void mh_msgset_first_current (mu_mailbox_t mbox, mu_msgset_t msgset);
size_t mh_msgset_first (mu_msgset_t msgset);
size_t mh_msgset_first_uid (mu_msgset_t msgset);
int mh_msgset_single_message (mu_msgset_t msgset);
char *mh_get_dir (void);
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,
int mh_is_my_name (const char *name);
char * mh_my_email (void);
int mh_iterate (mu_mailbox_t mbox, mh_msgset_t *msgset,
mh_iterator_fp itr, void *data);
size_t mh_get_message (mu_mailbox_t mbox, size_t seqno, mu_message_t *mesg);
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,
mu_message_t msg, mu_stream_t output);
void mhl_format_destroy (mu_list_t *fmt);
void mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset,
void mh_seq_add (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
int flags);
int mh_seq_delete (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset,
int mh_seq_delete (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
int flags);
const char *mh_seq_read (mu_mailbox_t mbox, const char *name, int flags);
......
......@@ -577,32 +577,6 @@ mh_find_file (const char *name, char **resolved_name)
}
int
mh_iterate (mu_mailbox_t mbox, mh_msgset_t *msgset,
mh_iterator_fp itr, void *data)
{
int rc;
size_t i;
for (i = 0; i < msgset->count; i++)
{
mu_message_t msg;
size_t num;
num = msgset->list[i];
if ((rc = mu_mailbox_get_message (mbox, num, &msg)) != 0)
{
mu_error (_("cannot get message %lu: %s"),
(unsigned long) num, mu_strerror (rc));
return 1;
}
itr (mbox, msg, num, data);
}
return 0;
}
int
mh_spawnp (const char *prog, const char *file)
{
struct mu_wordsplit ws;
......@@ -1039,19 +1013,16 @@ mh_draft_message (const char *name, const char *msgspec, char **pname)
else
{
char *argv[2];
mh_msgset_t msgset;
mu_msgset_t msgset;
argv[0] = (char*) msgspec;
argv[1] = NULL;
mh_msgset_parse (mbox, &msgset, 1, argv, "cur");
if (msgset.count > 1)
mh_msgset_parse (&msgset, mbox, 1, argv, "cur");
if (!mh_msgset_single_message (msgset))
mu_error (_("only one message at a time!"));
else
{
mh_msgset_uids (mbox, &msgset);
uid = msgset.list[0];
}
mh_msgset_free (&msgset);
uid = mh_msgset_first_uid (msgset);
mu_msgset_free (msgset);
}
mu_url_sget_path (url, &path);
......
......@@ -16,6 +16,7 @@
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <mh.h>
#include <mailutils/sys/msgset.h>
static char *
private_sequence_name (const char *name)
......@@ -62,118 +63,124 @@ delete_sequence (mu_mailbox_t mbox, const char *name, int private)
write_sequence (mbox, name, NULL, private);
}
void
mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset, int flags)
struct format_closure
{
const char *value = mh_seq_read (mbox, name, flags);
char *new_value, *p;
const char *buf;
size_t i, len;
mu_stream_t stream;
mu_mailbox_t mailbox;
};
delete_sequence (mbox, name, !(flags & SEQ_PRIVATE));
static int
format_sequence (void *item, void *data)
{
struct mu_msgrange *r = item;
struct format_closure *clos = data;
int rc;
size_t beg, end;
if (flags & SEQ_ZERO)
value = NULL;
if (value)
len = strlen (value);
if (clos->mailbox)
{
rc = mu_mailbox_translate (clos->mailbox,
MU_MAILBOX_MSGNO_TO_UID,
r->msg_beg, &beg);
if (rc)
return rc;
}
else
beg = r->msg_beg;
if (r->msg_beg == r->msg_end)
rc = mu_stream_printf (clos->stream, " %lu", (unsigned long) beg);
else
len = 0;
len++;
for (i = 0; i < mset->count; i++)
{
buf = mu_umaxtostr (0, mset->list[i]);
len += strlen (buf) + 1;
if (clos->mailbox)
{
rc = mu_mailbox_translate (clos->mailbox,
MU_MAILBOX_MSGNO_TO_UID,
r->msg_end, &end);
if (rc)
return rc;
}
else
end = r->msg_end;
if (beg + 1 == end)
rc = mu_stream_printf (clos->stream, " %lu %lu",
(unsigned long) beg,
(unsigned long) end);
else
rc = mu_stream_printf (clos->stream, " %lu-%lu",
(unsigned long) beg,
(unsigned long) end);
}
return rc;
}
new_value = xmalloc (len + 1);
if (value)
strcpy (new_value, value);
static void
save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
int flags)
{
mu_list_t list;
mu_msgset_get_list (mset, &list);
if (mu_list_is_empty (list))
write_sequence (mset->mbox, name, NULL, flags & SEQ_PRIVATE);
else
new_value[0] = 0;
p = new_value + strlen (new_value);
*p++ = ' ';
for (i = 0; i < mset->count; i++)
{
p += sprintf (p, "%s", mu_umaxtostr (0, mset->list[i]));
*p++ = ' ';
struct format_closure clos;
int rc;
mu_transport_t trans[2];
rc = mu_memory_stream_create (&clos.stream, MU_STREAM_RDWR);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_memory_stream_create", NULL, rc);
exit (1);
}
clos.mailbox = mset->mbox;
rc = mu_list_foreach (list, format_sequence, &clos);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_list_foreach", NULL, rc);
exit (1);
}
mu_stream_write (clos.stream, "", 1, NULL);
mu_stream_ioctl (clos.stream, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
trans);
write_sequence (mbox, name, (char*)trans[0], flags & SEQ_PRIVATE);
mu_stream_unref (clos.stream);
}
*p = 0;
write_sequence (mbox, name, new_value, flags & SEQ_PRIVATE);
/* FIXME
if (mu_c_strcasecmp (name, "cur") == 0)
current_message = strtoul (new_value, NULL, 0);
*/
free (new_value);
}
static int
cmp_msgnum (const void *a, const void *b)
void
mh_seq_add (mu_mailbox_t mbox, const char *name, mu_msgset_t mset, int flags)
{
const size_t *as = a;
const size_t *bs = b;
if (*as < *bs)
return -1;
if (*as > *bs)
return 1;
return 0;
const char *value = mh_seq_read (mbox, name, flags);
delete_sequence (mbox, name, !(flags & SEQ_PRIVATE));
if (value && !(flags & SEQ_ZERO))
{
mu_msgset_t oldset;
mh_msgset_parse_string (&oldset, mbox, value, "cur");
mu_msgset_add (oldset, mset);
save_sequence (mbox, name, oldset, flags);
mu_msgset_free (oldset);
}
else
save_sequence (mbox, name, mset, flags);
}
int
mh_seq_delete (mu_mailbox_t mbox, const char *name,
mh_msgset_t *mset, int flags)
mu_msgset_t mset, int flags)
{
const char *value = mh_seq_read (mbox, name, flags);
char *new_val;
char *p;
size_t i, count;
struct mu_wordsplit ws;
mu_msgset_t oldset;
if (!value)
return 0;
if (mu_wordsplit (value, &ws, MU_WRDSF_DEFFLAGS))
{
mu_error (_("cannot split line `%s': %s"), value,
mu_wordsplit_strerror (&ws));
return 0;
}
for (i = 0; i < ws.ws_wordc; i++)
{
char *p;
size_t num = strtoul (ws.ws_wordv[i], &p, 10);
if (*p)
continue;
if (bsearch (&num, mset->list, mset->count, sizeof (mset->list[0]),
cmp_msgnum))
{
free (ws.ws_wordv[i]);
ws.ws_wordv[i] = NULL;
}
}
new_val = xstrdup (value);
p = new_val;
count = 0;
for (i = 0; i < ws.ws_wordc; i++)
{
if (ws.ws_wordv[i])
{
strcpy (p, ws.ws_wordv[i]);
p += strlen (p);
*p++ = ' ';
count++;
}
}
*p = 0;
write_sequence (mbox, name, count > 0 ? new_val : NULL, flags & SEQ_PRIVATE);
mu_wordsplit_free (&ws);
free (new_val);
mh_msgset_parse_string (&oldset, mbox, value, "cur");
mu_msgset_sub (oldset, mset);
save_sequence (mbox, name, oldset, flags);
mu_msgset_free (oldset);
return 0;
}
......
......@@ -158,7 +158,7 @@ static int width = 80;
static char *charset; /* Charset for output file names. NULL means
no recoding is necessary. */
static mh_msgset_t msgset;
static mu_msgset_t msgset;
static mu_mailbox_t mbox;
static mu_message_t message;
static msg_part_t req_part;
......@@ -1369,7 +1369,7 @@ list_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
}
int
list_message (mu_message_t msg, size_t num)
list_message (mu_message_t msg)
{
size_t uid;
msg_part_t part;
......@@ -1381,10 +1381,10 @@ list_message (mu_message_t msg, size_t num)
return 0;
}
void
list_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
list_iterator (size_t num, mu_message_t msg, void *data)
{
list_message (msg, num);
return list_message (msg);
}
int
......@@ -1396,9 +1396,9 @@ mhn_list ()
printf (_(" msg part type/subtype size description\n"));
if (message)
rc = list_message (message, 0);
rc = list_message (message);
else
rc = mh_iterate (mbox, &msgset, list_iterator, NULL);
rc = mu_msgset_foreach_message (msgset, list_iterator, NULL);
return rc;
}
......@@ -1609,8 +1609,8 @@ show_message (mu_message_t msg, size_t num, void *data)
return 0;
}
void
show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
show_iterator (size_t num, mu_message_t msg, void *data)
{
msg_part_t part;
......@@ -1618,6 +1618,7 @@ show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
part = msg_part_create (num);
show_message (msg, num, data);
msg_part_destroy (part);
return 0;
}
int
......@@ -1630,7 +1631,7 @@ mhn_show ()
if (message)
rc = show_message (message, 0, mu_strout);
else
rc = mh_iterate (mbox, &msgset, show_iterator, mu_strout);
rc = mu_msgset_foreach_message (msgset, show_iterator, mu_strout);
mu_stream_flush (mu_strout);
return rc;
}
......@@ -1855,10 +1856,11 @@ store_message (mu_message_t msg, void *data)
msg_part_destroy (part);
}
void
store_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
store_iterator (size_t num, mu_message_t msg, void *data)
{
store_message (msg, data);
return 0;
}
int
......@@ -1876,7 +1878,7 @@ mhn_store ()
store_message (message, p);
}
else
rc = mh_iterate (mbox, &msgset, store_iterator, NULL);
rc = mu_msgset_foreach_message (msgset, store_iterator, NULL);
return rc;
}
......@@ -2982,7 +2984,7 @@ main (int argc, char **argv)
else
{
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
}
switch (mode)
......
......@@ -50,13 +50,14 @@ opt_handler (int key, char *arg, struct argp_state *state)
return 0;
}
void
mhpath (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
static int
mhpath (size_t num, mu_message_t msg, void *data)
{
size_t uid;
mh_message_number (msg, &uid);
printf ("%s/%s\n", (char*) data, mu_umaxtostr (0, uid));
return 0;
}
int
......@@ -67,7 +68,7 @@ main (int argc, char **argv)
mu_url_t url = NULL;
char *mhdir;
size_t total;
mh_msgset_t msgset;
mu_msgset_t msgset;
int status;
const char *current_folder;
......@@ -125,9 +126,9 @@ main (int argc, char **argv)
/* Mhpath expands and sorts the message list `msgs' and
writes the full pathnames of the messages to the standard
output separated by newlines. */
mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur");
status = mh_iterate (mbox, &msgset, mhpath, mhdir);
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
status = mu_msgset_foreach_message (msgset, mhpath, mhdir);
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
return status;
return status != 0;
}
......
......@@ -63,13 +63,19 @@ opt_handler (int key, char *arg, struct argp_state *state)
return 0;
}
static int
_print_number (size_t n, void *data)
{
printf ("%lu\n", (unsigned long) n);
return 0;
}
int
main (int argc, char **argv)
{
int index;
mu_mailbox_t mbox;
mh_msgset_t msgset;
size_t i;
mu_msgset_t msgset;
/* Native Language Support */
MU_APP_INIT_NLS ();
......@@ -82,12 +88,11 @@ main (int argc, char **argv)
argv += index;
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
if (uid_option)
mh_msgset_uids (mbox, &msgset);
for (i = 0; i < msgset.count; i++)
printf ("%lu\n", (unsigned long) msgset.list[i]);
mu_msgset_foreach_msguid (msgset, _print_number, NULL);
else
mu_msgset_foreach_msgno (msgset, _print_number, NULL);
return 0;
}
......
......@@ -21,9 +21,6 @@
#include <regex.h>
#include <pick.h>
#include <pick-gram.h>
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
#include <obstack.h>
static char doc[] = N_("GNU MH pick")"\v"
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 */
static mu_list_t lexlist; /* List of input tokens */
static struct obstack msgno_stk; /* Stack of selected message numbers */
static size_t msgno_count; /* Number of items on the stack */
static mu_msgset_t picked_message_uids;
static void
add_sequence (char *name)
......@@ -282,34 +278,26 @@ opt_handler (int key, char *arg, struct argp_state *state)
return 0;
}
void
pick_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
static int
pick_message (size_t num, mu_message_t msg, void *data)
{
if (pick_eval (msg))
{
mh_message_number (msg, &num);
if (list)
printf ("%s\n", mu_umaxtostr (0, num));
if (seq_list)
{
obstack_grow (&msgno_stk, &num, sizeof (num));
msgno_count++;
}
if (picked_message_uids)
mu_msgset_add_range (picked_message_uids, num, num, MU_MSGSET_UID);
}
return 0;
}
struct pick_closure
{
mu_mailbox_t mbox;
mh_msgset_t *msgset;
};
static int
action_add (void *item, void *data)
{
struct pick_closure *clos = data;
mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags);
mu_mailbox_t mbox = data;
mh_seq_add (mbox, (char *)item, picked_message_uids, seq_flags);
return 0;
}
......@@ -356,7 +344,7 @@ main (int argc, char **argv)
int status;
int index;
mu_mailbox_t mbox;
mh_msgset_t msgset;
mu_msgset_t msgset;
int interactive = mh_interactive_mode_p ();
MU_APP_INIT_NLS ();
......@@ -397,21 +385,13 @@ main (int argc, char **argv)
argv += index;
if (seq_list)
obstack_init (&msgno_stk);
mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID);
mh_msgset_parse (mbox, &msgset, argc, argv, "all");
status = mh_iterate (mbox, &msgset, pick_message, NULL);
mh_msgset_parse (&msgset, mbox, argc, argv, "all");
status = mu_msgset_foreach_message (msgset, pick_message, NULL);
if (seq_list)
{
struct pick_closure clos;
mh_msgset_t msgset;
msgset.count = msgno_count;
msgset.list = obstack_finish (&msgno_stk);
clos.mbox = mbox;
clos.msgset = &msgset;
mu_list_foreach (seq_list, action_add, &clos);
}
if (picked_message_uids)
mu_list_foreach (seq_list, action_add, mbox);
mh_global_save_state ();
mu_mailbox_close (mbox);
......
......@@ -201,8 +201,8 @@ refile (mu_message_t msg)
enumerate_folders (refile_folder, msg);
}
void
refile_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
int
refile_iterator (size_t num, mu_message_t msg, void *data)
{
enumerate_folders (refile_folder, msg);
if (!link_flag)
......@@ -211,13 +211,14 @@ refile_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
mu_message_get_attribute (msg, &attr);
mu_attribute_set_deleted (attr);
}
return 0;
}
int
main (int argc, char **argv)
{
int index;
mh_msgset_t msgset;
mu_msgset_t msgset;
mu_mailbox_t mbox;
int status, i, j;
......@@ -262,9 +263,9 @@ main (int argc, char **argv)
else
{
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
status = mh_iterate (mbox, &msgset, refile_iterator, NULL);
status = mu_msgset_foreach_message (msgset, refile_iterator, NULL);
mu_mailbox_expunge (mbox);
mu_mailbox_close (mbox);
......
......@@ -112,7 +112,7 @@ static int width = 80;
struct mh_whatnow_env wh_env = { 0 };
static int initial_edit = 1;
static const char *whatnowproc;
static mh_msgset_t msgset;
static mu_msgset_t msgset;
static mu_mailbox_t mbox;
static int build_only = 0; /* --build flag */
static int query_mode = 0; /* --query flag */
......@@ -281,6 +281,7 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
int rc;
mu_message_t msg;
struct stat st;
size_t msgno;
/* First check if the draft exists */
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)
unlink (wh->draftfile);
break;
}
rc = mu_mailbox_get_message (mbox, msgset.list[0], &msg);
msgno = mh_msgset_first (msgset);
rc = mu_mailbox_get_message (mbox, msgno, &msg);
if (rc)
{
mu_error (_("cannot read message %s: %s"),
mu_umaxtostr (0, msgset.list[0]),
mu_umaxtostr (0, msgno),
mu_strerror (rc));
exit (1);
}
......@@ -349,11 +351,11 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
mu_message_get_header (tmp_msg, &hdr);
text = obstack_finish (&fcc_stack);
mu_header_set_value (hdr, MU_HEADER_FCC, text, 0);
mh_format (&format, tmp_msg, msgset.list[0], width, &buf);
mh_format (&format, tmp_msg, msgno, width, &buf);
mu_message_destroy (&tmp_msg, NULL);
}
else
mh_format (&format, msg, msgset.list[0], width, &buf);
mh_format (&format, msg, msgno, width, &buf);
mu_stream_write (str, buf, strlen (buf), NULL);
......@@ -409,8 +411,8 @@ main (int argc, char **argv)
}
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur");
if (msgset.count != 1)
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
if (!mh_msgset_single_message (msgset))
{
mu_error (_("only one message at a time!"));
return 1;
......
......@@ -50,12 +50,13 @@ opt_handler (int key, char *arg, struct argp_state *state)
return 0;
}
void
rmm (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
static int
rmm (size_t num, mu_message_t msg, void *data)
{
mu_attribute_t attr;
mu_message_get_attribute (msg, &attr);
mu_attribute_set_deleted (attr);
return 0;
}
int
......@@ -63,7 +64,7 @@ main (int argc, char **argv)
{
int index = 0;
mu_mailbox_t mbox;
mh_msgset_t msgset;
mu_msgset_t msgset;
int status;
/* Native Language Support */
......@@ -75,9 +76,9 @@ main (int argc, char **argv)
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur");
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
status = mh_iterate (mbox, &msgset, rmm, NULL);
status = mu_msgset_foreach_message (msgset, rmm, NULL);
mu_mailbox_expunge (mbox);
mu_mailbox_close (mbox);
......
......@@ -75,9 +75,9 @@ static int header;
static mh_format_t format;
static mh_msgset_t msgset;
static mu_msgset_t msgset;
void list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data);
static int list_message (size_t num, mu_message_t msg, void *data);
void print_header (mu_mailbox_t mbox);
void clear_screen (void);
......@@ -153,7 +153,7 @@ action (mu_observer_t o, size_t type, void *data, void *action_data)
counter++;
mu_mailbox_get_message (mbox, counter, &msg);
mh_message_number (msg, &num);
list_message (mbox, msg, num, NULL);
list_message (num, msg, NULL);
}
return 0;
}
......@@ -201,13 +201,11 @@ main (int argc, char **argv)
else
{
mu_mailbox_messages_count (mbox, &total);
mh_msgset_parse (mbox, &msgset, argc, argv, "all");
if (reverse)
mh_msgset_reverse (&msgset);
mh_msgset_parse (&msgset, mbox, argc, argv, "all");
print_header (mbox);
status = mh_iterate (mbox, &msgset, list_message, NULL);
status = mu_msgset_foreach_dir_message (msgset, reverse,
list_message, NULL);
}
if (total == 0)
......@@ -282,8 +280,8 @@ clear_screen ()
}
}
void
list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
static int
list_message (size_t num, mu_message_t msg, void *data)
{
char *buffer;
int len;
......@@ -294,4 +292,5 @@ list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
if (len > 0 && buffer[len-1] != '\n')
printf("\n");
free (buffer);
return 0;
}
......
......@@ -737,6 +737,27 @@ _action_send (void *item, void *data)
return 0;
}
static int
_add_to_mesg_list (size_t num, mu_message_t msg, void *data)
{
char const *path = data;
struct list_elt *elt;
size_t uid;
int rc;
elt = xmalloc (sizeof *elt);
elt->msg = msg;
mu_message_get_uid (msg, &uid);
elt->file_name = mu_make_file_name (path, mu_umaxtostr (0, uid));
rc = mu_list_append (mesg_list, elt);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", NULL, rc);
exit (1);
}
return 0;
}
int
main (int argc, char **argv)
{
......@@ -758,13 +779,12 @@ main (int argc, char **argv)
if (draftfolder)
{
mh_msgset_t msgset;
mu_msgset_t msgset;
mu_url_t url;
const char *path;
size_t i;
mbox = mh_open_folder (draftfolder, MU_STREAM_RDWR|MU_STREAM_CREAT);
mh_msgset_parse (mbox, &msgset, argc, argv, draftmessage);
mh_msgset_parse (&msgset, mbox, argc, argv, draftmessage);
mu_mailbox_get_url (mbox, &url);
mu_url_sget_path (url, &path);
if ((rc = mu_list_create (&mesg_list)))
......@@ -772,25 +792,9 @@ main (int argc, char **argv)
mu_error (_("cannot create message list: %s"), mu_strerror (rc));
exit (1);
}
for (i = 0; i < msgset.count; i++)
{
struct list_elt *elt;
size_t uid;
elt = xmalloc (sizeof *elt);
mu_mailbox_get_message (mbox, msgset.list[i], &elt->msg);
mu_message_get_uid (elt->msg, &uid);
elt->file_name =
mu_make_file_name (path, mu_umaxtostr (0, uid));
rc = mu_list_append (mesg_list, elt);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", NULL, rc);
exit (1);
}
}
mu_msgset_foreach_message (msgset, _add_to_mesg_list, (void*)path);
mh_msgset_free (&msgset);
mu_msgset_free (msgset);
}
else
{
......
......@@ -92,7 +92,10 @@ static int limit;
static int verbose;
static mu_mailbox_t mbox;
static const char *mbox_path;
static mh_msgset_t msgset;
static size_t *msgarr;
static size_t msgcount;
static size_t current_num;
#define ACTION_REORDER 0
......@@ -416,17 +419,17 @@ shell_sort ()
int h, s, i, j;
size_t hold;
for (h = startdst (msgset.count, &s); s > 0; s--, h = prevdst (h))
for (h = startdst (msgcount, &s); s > 0; s--, h = prevdst (h))
{
if (verbose > 1)
fprintf (stderr, _("distance %d\n"), h);
for (j = h; j < msgset.count; j++)
for (j = h; j < msgcount; j++)
{
hold = msgset.list[j];
hold = msgarr[j];
for (i = j - h;
i >= 0 && comp0 (hold, msgset.list[i]) < 0; i -= h)
msgset.list[i + h] = msgset.list[i];
msgset.list[i + h] = hold;
i >= 0 && comp0 (hold, msgarr[i]) < 0; i -= h)
msgarr[i + h] = msgarr[i];
msgarr[i + h] = hold;
}
}
}
......@@ -467,12 +470,12 @@ transpose(size_t i, size_t n)
{
size_t j;
for (j = i+1; j < msgset.count; j++)
if (msgset.list[j] == n)
for (j = i+1; j < msgcount; j++)
if (msgarr[j] == n)
{
size_t t = msgset.list[i];
msgset.list[i] = msgset.list[j];
msgset.list[j] = t;
size_t t = msgarr[i];
msgarr[i] = msgarr[j];
msgarr[j] = t;
break;
}
}
......@@ -489,26 +492,25 @@ void
sort ()
{
size_t *oldlist, i;
oldlist = xmalloc (msgset.count * sizeof (*oldlist));
memcpy (oldlist, msgset.list, msgset.count * sizeof (*oldlist));
oldlist = xmalloc (msgcount * sizeof (*oldlist));
memcpy (oldlist, msgarr, msgcount * sizeof (*oldlist));
switch (algorithm)
{
case ARG_QUICKSORT:
qsort(msgset.list, msgset.count, sizeof (msgset.list[0]),
comp);
qsort (msgarr, msgcount, sizeof (msgarr[0]), comp);
break;
case ARG_SHELL:
shell_sort();
shell_sort ();
break;
}
switch (action)
{
case ACTION_LIST:
for (i = 0; i < msgset.count; i++)
list_message (msgset.list[i]);
for (i = 0; i < msgcount; i++)
list_message (msgarr[i]);
break;
default:
......@@ -519,16 +521,16 @@ sort ()
if (verbose)
fprintf (stderr, _("Transpositions:\n"));
for (i = 0, got_signal = 0; !got_signal && i < msgset.count; i++)
for (i = 0, got_signal = 0; !got_signal && i < msgcount; i++)
{
if (msgset.list[i] != oldlist[i])
if (msgarr[i] != oldlist[i])
{
size_t old_num, new_num;
mu_message_t msg;
mu_mailbox_get_message (mbox, oldlist[i], &msg);
mh_message_number (msg, &old_num);
mu_mailbox_get_message (mbox, msgset.list[i], &msg);
mu_mailbox_get_message (mbox, msgarr[i], &msg);
mh_message_number (msg, &new_num);
transpose (i, oldlist[i]);
if (verbose)
......@@ -563,6 +565,38 @@ sort ()
mh_mailbox_set_cur (mbox, current_num);
}
}
static int
_add_msgno (size_t n, void *data)
{
size_t *pidx = data;
msgarr[*pidx] = n;
++*pidx;
return 0;
}
static void
fill_msgarr (mu_msgset_t msgset)
{
size_t i;
int rc;
rc = mu_msgset_count (msgset, &msgcount);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_count", NULL, rc);
exit (1);
}
msgarr = xcalloc (msgcount, sizeof (msgarr[0]));
i = 0;
rc = mu_msgset_foreach_msgno (msgset, _add_msgno, &i);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_foreach_msgno", NULL, rc);
exit (1);
}
}
/* Main */
......@@ -572,6 +606,7 @@ main (int argc, char **argv)
{
int index;
mu_url_t url;
mu_msgset_t msgset;
MU_APP_INIT_NLS ();
mh_argp_init ();
......@@ -597,7 +632,9 @@ main (int argc, char **argv)
mh_mailbox_get_cur (mbox, &current_num);
mh_msgset_parse (mbox, &msgset, argc, argv, "all");
mh_msgset_parse (&msgset, mbox, argc, argv, "all");
fill_msgarr (msgset);
mu_msgset_free (msgset);
sort ();
mh_global_save_state ();
mu_mailbox_destroy (&mbox);
......
......@@ -25,7 +25,7 @@ mark -sequence andro -add 3-5
sed -n '/^andro:/{s/ */ /g;s/ $//;p;}' Mail/inbox/.mh_sequences
],
[0],
[andro: 2 3 4 5
[andro: 2-5
])
MH_CHECK([mark -add -zero],[mark01 mark-add-zero],[
......@@ -48,7 +48,7 @@ mark -nopublic -sequence andro -add 1 2 3
sed -n '/^atr-andro/{s/ */ /g;s/ $//;s/^[[^:]]*:/atr-andro:/;p;}' Mail/context
],
[0],
[atr-andro: 1 2 3
[atr-andro: 1-3
])
MH_CHECK([mark -del],[mark03 mark-del],[
......@@ -67,7 +67,7 @@ MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
echo 'Current-Folder: inbox' > Mail/context
inbox=`pwd`/Mail/inbox
cat > Mail/context <<EOT
atr-andro-$inbox: 2 3 4 5
atr-andro-$inbox: 2-5
EOT
mark -nopublic -sequence andro -del 3
sed -n '/^atr-andro/{s/ */ /g;s/ $//;s/^[[^:]]*:/atr-andro:/;p;}' Mail/context
......
......@@ -17,6 +17,13 @@
#include <mh.h>
static int
_add_to_list (size_t num, mu_message_t msg, void *data)
{
mu_list_t list = data;
return mu_list_append (list, msg);
}
void
mh_whatnow_env_from_environ (struct mh_whatnow_env *wh)
{
......@@ -39,38 +46,15 @@ mh_whatnow_env_from_environ (struct mh_whatnow_env *wh)
wh->anno_field = NULL;
else
{
size_t i;
struct mu_wordsplit ws;
mh_msgset_t msgset;
mu_msgset_t msgset;
mu_mailbox_t mbox = mh_open_folder (folder, MU_STREAM_RDWR);
if (mu_wordsplit (p, &ws,
MU_WRDSF_DEFFLAGS & ~MU_WRDSF_CESCAPES))
{
mu_error (_("cannot parse mhmessages (%s): %s"), p,
mu_wordsplit_strerror (&ws));
exit (1);
}
mh_msgset_parse (mbox, &msgset, ws.ws_wordc, ws.ws_wordv, "cur");
mu_wordsplit_free (&ws);
mh_msgset_parse_string (&msgset, mbox, p, "cur");
wh->mbox = mbox;
mu_list_create (&wh->anno_list);
for (i = 0; i < msgset.count; i++)
{
mu_message_t msg;
int rc = mu_mailbox_get_message (mbox, msgset.list[i], &msg);
if (rc)
{
mu_error (_("cannot get message %lu from %s: %s"),
(unsigned long) msgset.list[i],
folder,
mu_strerror (rc));
continue;
}
mu_list_append (wh->anno_list, msg);
}
mh_msgset_free (&msgset);
mu_msgset_foreach_message (msgset, _add_to_list, wh->anno_list);
mu_msgset_free (msgset);
/* FIXME:
wh->anno_inplace = getenv ("mhinplace");
*/
......
......@@ -118,13 +118,13 @@ parse_msgset (const char *arg)
mu_msgset_t msgset;
char *p;
status = mu_msgset_create (&msgset, NULL, 0);
status = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, status);
return NULL;
}
status = mu_msgset_parse_imap (msgset, arg, &p);
status = mu_msgset_parse_imap (msgset, MU_MSGSET_NUM, arg, &p);
if (status)
{
mu_error (_("failed to parse message set near \"%s\": %s"),
......
......@@ -19,7 +19,7 @@
#include <mailutils/mailutils.h>
static void
parse_msgset (char *arg, struct mu_msgrange *range)
parse_msgrange (char *arg, struct mu_msgrange *range)
{
size_t msgnum;
char *p;
......@@ -52,14 +52,36 @@ parse_msgset (char *arg, struct mu_msgrange *range)
range->msg_end = msgnum;
}
mu_msgset_t
parse_msgset (const char *arg, mu_mailbox_t mbox,
int create_mode, int parse_mode)
{
int rc;
mu_msgset_t msgset;
char *end;
MU_ASSERT (mu_msgset_create (&msgset, mbox, create_mode));
if (arg)
{
rc = mu_msgset_parse_imap (msgset, parse_mode, arg, &end);
if (rc)
{
mu_error ("mu_msgset_parse_imap: %s near %s",
mu_strerror (rc), end);
exit (1);
}
}
return msgset;
}
int
main (int argc, char **argv)
{
int i;
char *msgset_string = NULL;
mu_msgset_t msgset;
int rc;
int flags = 0;
int create_mode = MU_MSGSET_NUM;
int parse_mode = MU_MSGSET_NUM;
mu_mailbox_t mbox = NULL;
mu_set_program_name (argv[0]);
......@@ -70,14 +92,23 @@ main (int argc, char **argv)
if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
{
mu_printf ("usage: %s [-msgset=SET] [-add X[:Y]] [-del X:[Y]]...\n",
mu_printf ("usage: %s [-msgset[uid]=SET] [-uid] [-add[uid]=X[:Y]] [-del[uid]=X[:Y]] "
"[-addset[uid]=SET] [-delset[uid]=SET] ...\n",
mu_program_name);
return 0;
}
else if (strncmp (arg, "-msgset=", 8) == 0)
msgset_string = arg + 8;
{
parse_mode = MU_MSGSET_NUM;
msgset_string = arg + 8;
}
else if (strncmp (arg, "-msgsetuid=", 11) == 0)
{
parse_mode = MU_MSGSET_UID;
msgset_string = arg + 11;
}
else if (strcmp (arg, "-uid") == 0)
flags |= MU_MSGSET_UID;
create_mode = MU_MSGSET_UID;
else if (strncmp (arg, "-mailbox=", 9) == 0)
{
MU_ASSERT (mu_mailbox_create (&mbox, arg + 9));
......@@ -87,18 +118,7 @@ main (int argc, char **argv)
break;
}
MU_ASSERT (mu_msgset_create (&msgset, mbox, flags));
if (msgset_string)
{
char *end;
rc = mu_msgset_parse_imap (msgset, msgset_string, &end);
if (rc)
{
mu_error ("mu_msgset_parse_imap: %s near %s",
mu_strerror (rc), end);
return 1;
}
}
msgset = parse_msgset (msgset_string, mbox, create_mode, parse_mode);
for (; i < argc; i++)
{
......@@ -107,15 +127,95 @@ main (int argc, char **argv)
if (strncmp (arg, "-add=", 5) == 0)
{
parse_msgset (arg + 5, &range);
MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg,
range.msg_end));
parse_msgrange (arg + 5, &range);
MU_ASSERT (mu_msgset_add_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_NUM));
}
else if (strncmp (arg, "-sub=", 5) == 0)
{
parse_msgset (arg + 5, &range);
MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg,
range.msg_end));
parse_msgrange (arg + 5, &range);
MU_ASSERT (mu_msgset_sub_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_NUM));
}
else if (strncmp (arg, "-adduid=", 8) == 0)
{
parse_msgrange (arg + 8, &range);
MU_ASSERT (mu_msgset_add_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_UID));
}
else if (strncmp (arg, "-subuid=", 8) == 0)
{
parse_msgrange (arg + 8, &range);
MU_ASSERT (mu_msgset_sub_range (msgset,
range.msg_beg, range.msg_end,
MU_MSGSET_UID));
}
else if (strncmp (arg, "-addset", 7) == 0)
{
mu_msgset_t tset;
int m;
arg += 7;
if (strncmp (arg, "uid", 3) == 0)
{
m = MU_MSGSET_UID;
arg += 3;
}
else
m = MU_MSGSET_NUM;
if (*arg == '=')
arg++;
else
{
mu_error ("unknown option %s", argv[i]);
return 1;
}
tset = parse_msgset (arg, mbox, m, m);
if (!msgset)
msgset = tset;
else
{
MU_ASSERT (mu_msgset_add (msgset, tset));
mu_msgset_free (tset);
}
}
else if (strncmp (arg, "-subset=", 8) == 0)
{
mu_msgset_t tset;
int m;
arg += 7;
if (strncmp (arg, "uid", 3) == 0)
{
m = MU_MSGSET_UID;
arg += 3;
}
else
m = MU_MSGSET_NUM;
if (*arg == '=')
arg++;
else
{
mu_error ("unknown option %s", argv[i]);
return 1;
}
tset = parse_msgset (arg, mbox, m, m);
if (!msgset)
{
mu_error ("no initial message set");
exit (1);
}
else
{
MU_ASSERT (mu_msgset_sub (msgset, tset));
mu_msgset_free (tset);
}
}
else if (strcmp (arg, "-neg") == 0)
{
......