summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-02-02 09:01:52 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-02-02 09:01:52 +0200
commit8360e84e5a673211488ee31c93922c987c057007 (patch)
tree7ab593a8ccefc11c39c4bba43cc687ecb831cfec
parent34025229771c88e1b8118c40553a95ec4e2fc1c8 (diff)
downloadmailutils-8360e84e5a673211488ee31c93922c987c057007.tar.gz
mailutils-8360e84e5a673211488ee31c93922c987c057007.tar.bz2
New iterator functions: mu_iterator_skip_while and mu_iterator_skip_until
The mu_iterator_skip_while function continues iteration while the supplied predicate function returns true. The mu_iterator_skip_until function continues iteration until the supplied predicate function returns true. * include/mailutils/iterator.h: Add new prototypes. * libmailutils/base/iterator.c: Implement new functions.
-rw-r--r--include/mailutils/iterator.h6
-rw-r--r--libmailutils/base/iterator.c65
2 files changed, 62 insertions, 9 deletions
diff --git a/include/mailutils/iterator.h b/include/mailutils/iterator.h
index 83278b122..2cf318a38 100644
--- a/include/mailutils/iterator.h
+++ b/include/mailutils/iterator.h
@@ -44,6 +44,12 @@ extern void mu_iterator_destroy (mu_iterator_t *);
extern int mu_iterator_first (mu_iterator_t);
extern int mu_iterator_next (mu_iterator_t);
extern int mu_iterator_skip (mu_iterator_t iterator, ssize_t count);
+extern int mu_iterator_skip_while (mu_iterator_t iterator,
+ int (*pred) (void *, void *),
+ void *data);
+extern int mu_iterator_skip_until (mu_iterator_t iterator,
+ int (*pred) (void *, void *),
+ void *data);
extern int mu_iterator_current (mu_iterator_t, void **pitem);
extern int mu_iterator_current_kv (mu_iterator_t,
const void **key, void **pitem);
diff --git a/libmailutils/base/iterator.c b/libmailutils/base/iterator.c
index 41bd6d486..cec176e94 100644
--- a/libmailutils/base/iterator.c
+++ b/libmailutils/base/iterator.c
@@ -62,7 +62,7 @@ mu_iterator_set_next (mu_iterator_t itr, int (*next) (void *))
int
mu_iterator_set_getitem (mu_iterator_t itr,
- int (*getitem) (void *, void **, const void **))
+ int (*getitem) (void *, void **, const void **))
{
if (!itr)
return EINVAL;
@@ -135,7 +135,7 @@ mu_iterator_dup (mu_iterator_t *piterator, mu_iterator_t orig)
{
mu_iterator_t iterator;
int status;
-
+
if (piterator == NULL)
return MU_ERR_OUT_PTR_NULL;
if (orig == NULL)
@@ -151,7 +151,7 @@ mu_iterator_dup (mu_iterator_t *piterator, mu_iterator_t orig)
free (iterator);
return status;
}
- iterator->is_advanced = orig->is_advanced;
+ iterator->is_advanced = orig->is_advanced;
iterator->dup = orig->dup;
iterator->destroy = orig->destroy;
iterator->first = orig->first;
@@ -160,7 +160,7 @@ mu_iterator_dup (mu_iterator_t *piterator, mu_iterator_t orig)
iterator->delitem = orig->delitem;
iterator->finished_p = orig->finished_p;
iterator->itrctl = orig->itrctl;
-
+
*piterator = iterator;
return 0;
}
@@ -173,7 +173,7 @@ mu_iterator_destroy (mu_iterator_t *piterator)
if ((*piterator)->destroy)
(*piterator)->destroy (*piterator, (*piterator)->owner);
-
+
free (*piterator);
*piterator = NULL;
}
@@ -208,14 +208,61 @@ mu_iterator_skip (mu_iterator_t iterator, ssize_t count)
}
int
+mu_iterator_skip_while (mu_iterator_t iterator,
+ int (*pred) (void *, void *),
+ void *data)
+{
+ int status;
+ if (!iterator || !pred)
+ return EINVAL;
+ do
+ {
+ if ((status = mu_iterator_next (iterator)) == 0)
+ {
+ void *item;
+ if ((status = mu_iterator_current (iterator, &item)) == 0)
+ if (!pred (item, data))
+ break;
+ }
+ }
+ while (status == 0);
+
+ return status;
+}
+
+int
+mu_iterator_skip_until (mu_iterator_t iterator,
+ int (*pred) (void *, void *),
+ void *data)
+{
+ int status;
+ if (!iterator || !pred)
+ return EINVAL;
+ do
+ {
+ if ((status = mu_iterator_next (iterator)) == 0)
+ {
+ void *item;
+ if ((status = mu_iterator_current (iterator, &item)) == 0)
+ if (pred (item, data))
+ break;
+ }
+ }
+ while (status == 0);
+
+ return status;
+}
+
+
+int
mu_iterator_current (mu_iterator_t iterator, void **pitem)
{
return mu_iterator_current_kv (iterator, NULL, pitem);
}
int
-mu_iterator_current_kv (mu_iterator_t iterator,
- const void **pkey, void **pitem)
+mu_iterator_current_kv (mu_iterator_t iterator,
+ const void **pkey, void **pitem)
{
void *ptr;
int rc = iterator->getitem (iterator->owner, &ptr, pkey);
@@ -278,7 +325,7 @@ int
mu_iterator_detach (mu_iterator_t *root, mu_iterator_t iterator)
{
mu_iterator_t itr, prev;
-
+
for (itr = *root, prev = NULL; itr; prev = itr, itr = itr->next_itr)
if (iterator == itr)
break;
@@ -290,7 +337,7 @@ mu_iterator_detach (mu_iterator_t *root, mu_iterator_t iterator)
else
*root = itr->next_itr;
}
-
+
return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.