diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-04-01 23:12:33 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-04-01 23:15:21 +0300 |
commit | 52fffebc9d359125c21130d93a67b225b4778457 (patch) | |
tree | b2645da46b613577b2ce58f1611dc8e6b2341b85 | |
parent | c73e770c70d3e358e65759130d7fdff047750a69 (diff) | |
download | mailutils-52fffebc9d359125c21130d93a67b225b4778457.tar.gz mailutils-52fffebc9d359125c21130d93a67b225b4778457.tar.bz2 |
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.
-rw-r--r-- | guimb/scm/sieve-core.scm | 17 | ||||
-rw-r--r-- | libmu_scm/mu_mailbox.c | 109 |
2 files changed, 118 insertions, 8 deletions
diff --git a/guimb/scm/sieve-core.scm b/guimb/scm/sieve-core.scm index 5a11c65ac..f5f335c7b 100644 --- a/guimb/scm/sieve-core.scm +++ b/guimb/scm/sieve-core.scm @@ -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 diff --git a/libmu_scm/mu_mailbox.c b/libmu_scm/mu_mailbox.c index 8a54fda1b..663755e16 100644 --- a/libmu_scm/mu_mailbox.c +++ b/libmu_scm/mu_mailbox.c @@ -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 () |