Commit 52fffebc 52fffebc9d359125c21130d93a67b225b4778457 by Sergey Poznyakoff

Implement mailbox iterators in Scheme.

* libmu_scm/mu_mailbox.c (struct mu_mailbox)<itr>: New member.
(mu_scm_mailbox_free): Destroy the iterator.
(mu_scm_mailbox_create0): Initialize itr to NULL.
(mu-mailbox-first-message, mu-mailbox-next-message)
(mu-mailbox-more-messages?): New function.
* guimb/scm/sieve-core.scm (sieve-run): Rewrite
main loop in the True Schemish Way.
1 parent c73e770c
......@@ -472,14 +472,15 @@
(if (not sieve-my-email)
(set! sieve-my-email (mu-username->email)))
; (DEBUG 1 "Mailbox: " sieve-mailbox)
(let ((count (mu-mailbox-messages-count sieve-mailbox)))
(do ((n 1 (1+ n)))
((> n count) #f)
(set! sieve-current-message
(mu-mailbox-get-message sieve-mailbox n))
(sieve-run-current-message thunk))
(sieve-close-mailboxes)))
(let msg-loop ((msg (mu-mailbox-first-message sieve-mailbox)))
(if (not (eof-object? msg))
(begin
(set! sieve-current-message msg)
(sieve-run-current-message thunk)
(msg-loop (mu-mailbox-next-message sieve-mailbox)))))
(sieve-close-mailboxes))
(define (sieve-command-line)
(catch #t
......
......@@ -18,6 +18,7 @@
Boston, MA 02110-1301 USA */
#include "mu_scm.h"
#include <mailutils/iterator.h>
static scm_t_bits mailbox_tag;
......@@ -26,6 +27,7 @@ static scm_t_bits mailbox_tag;
struct mu_mailbox
{
mu_mailbox_t mbox; /* Mailbox */
mu_iterator_t itr;
int noclose;
};
......@@ -40,6 +42,9 @@ static scm_sizet
mu_scm_mailbox_free (SCM mailbox_smob)
{
struct mu_mailbox *mum = (struct mu_mailbox *) SCM_CDR (mailbox_smob);
mu_iterator_destroy (&mum->itr);
if (!mum->noclose)
{
mu_mailbox_close (mum->mbox);
......@@ -112,6 +117,7 @@ mu_scm_mailbox_create0 (mu_mailbox_t mbox, int noclose)
mum = scm_gc_malloc (sizeof (struct mu_mailbox), "mailbox");
mum->mbox = mbox;
mum->itr = NULL;
mum->noclose = noclose;
SCM_RETURN_NEWSMOB (mailbox_tag, mum);
}
......@@ -409,6 +415,109 @@ SCM_DEFINE (scm_mu_mailbox_append_message, "mu-mailbox-append-message", 2, 0, 0,
}
#undef FUNC_NAME
/* Iterations */
#define ITROP(op, descr) \
do \
{ \
int status = op; \
if (status == MU_ERR_NOENT) \
return SCM_EOF_VAL; \
if (status) \
mu_scm_error (FUNC_NAME, status, \
"~A: " descr ": ~A", \
scm_list_2 (MBOX, \
scm_from_locale_string (mu_strerror (status)))); \
} \
while (0)
SCM_DEFINE (scm_mu_mailbox_first_message, "mu-mailbox-first-message", 1, 0, 0,
(SCM MBOX),
"Returns first message from the mailbox.")
#define FUNC_NAME s_scm_mu_mailbox_first_message
{
struct mu_mailbox *mum;
int status;
mu_message_t msg;
SCM_ASSERT (mu_scm_is_mailbox (MBOX), MBOX, SCM_ARG1, FUNC_NAME);
mum = (struct mu_mailbox *) SCM_CDR (MBOX);
if (!mum->itr)
{
status = mu_mailbox_get_iterator (mum->mbox, &mum->itr);
if (status)
mu_scm_error (FUNC_NAME, status,
"~A: cannot create iterator: ~A",
scm_list_2 (MBOX,
scm_from_locale_string (mu_strerror (status))));
}
ITROP (mu_iterator_first (mum->itr), "moving to the first message");
ITROP (mu_iterator_current (mum->itr, (void**)&msg),
"getting current message");
return mu_scm_message_create (MBOX, msg);
}
#undef FUNC_NAME
SCM_DEFINE (scm_mu_mailbox_next_message, "mu-mailbox-next-message", 1, 0, 0,
(SCM MBOX),
"Returns next message from the mailbox.")
#define FUNC_NAME s_scm_mu_mailbox_next_message
{
struct mu_mailbox *mum;
int status;
mu_message_t msg;
SCM_ASSERT (mu_scm_is_mailbox (MBOX), MBOX, SCM_ARG1, FUNC_NAME);
mum = (struct mu_mailbox *) SCM_CDR (MBOX);
if (!mum->itr)
{
status = mu_mailbox_get_iterator (mum->mbox, &mum->itr);
if (status)
mu_scm_error (FUNC_NAME, status,
"~A: cannot create iterator: ~A",
scm_list_2 (MBOX,
scm_from_locale_string (mu_strerror (status))));
ITROP (mu_iterator_first (mum->itr), "moving to the first message");
}
else
ITROP (mu_iterator_next (mum->itr), "advancing iterator");
ITROP (mu_iterator_current (mum->itr, (void**)&msg),
"getting current message");
return mu_scm_message_create (MBOX, msg);
}
#undef FUNC_NAME
SCM_DEFINE (scm_mu_mailbox_more_messages_p, "mu-mailbox-more-messages?", 1, 0, 0,
(SCM MBOX),
"Returns next message from the mailbox.")
#define FUNC_NAME s_scm_mu_mailbox_more_messages_p
{
struct mu_mailbox *mum;
int status;
SCM_ASSERT (mu_scm_is_mailbox (MBOX), MBOX, SCM_ARG1, FUNC_NAME);
mum = (struct mu_mailbox *) SCM_CDR (MBOX);
if (!mum->itr)
{
status = mu_mailbox_get_iterator (mum->mbox, &mum->itr);
if (status)
mu_scm_error (FUNC_NAME, status,
"~A: cannot create iterator: ~A",
scm_list_2 (MBOX,
scm_from_locale_string (mu_strerror (status))));
status = mu_iterator_first (mum->itr);
if (status == MU_ERR_NOENT)
return SCM_BOOL_F;
if (status)
mu_scm_error (FUNC_NAME, status,
"~A: cannot set iterator to the first message: ~A",
scm_list_2 (MBOX,
scm_from_locale_string (mu_strerror (status))));
}
return scm_from_bool (!!mu_iterator_is_done (mum->itr));
}
#undef FUNC_NAME
/* Initialize the module */
void
mu_scm_mailbox_init ()
......