summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-04-01 23:12:33 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-04-01 23:15:21 +0300
commit52fffebc9d359125c21130d93a67b225b4778457 (patch)
treeb2645da46b613577b2ce58f1611dc8e6b2341b85
parentc73e770c70d3e358e65759130d7fdff047750a69 (diff)
downloadmailutils-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.scm17
-rw-r--r--libmu_scm/mu_mailbox.c109
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 ()

Return to:

Send suggestions and report system problems to the System administrator.