diff options
26 files changed, 1186 insertions, 713 deletions
diff --git a/configure.ac b/configure.ac index 7251453cf..f28c42be4 100644 --- a/configure.ac +++ b/configure.ac @@ -1473,6 +1473,7 @@ AC_CONFIG_FILES([ libmailutils/diag/Makefile libmailutils/filter/Makefile libmailutils/imapio/Makefile + libmailutils/list/Makefile libmailutils/mailbox/Makefile libmailutils/mailer/Makefile libmailutils/mime/Makefile diff --git a/include/mailutils/sys/list.h b/include/mailutils/sys/list.h index ba00ae7ee..6769e78be 100644 --- a/include/mailutils/sys/list.h +++ b/include/mailutils/sys/list.h @@ -46,6 +46,14 @@ struct _mu_list struct _mu_iterator *itr; }; +#define DESTROY_ITEM(list, elt) \ + do \ + { \ + if ((list)->destroy_item) \ + (list)->destroy_item ((elt)->item); \ + } \ + while (0) + extern void _mu_list_clear (mu_list_t list); extern void _mu_list_insert_sublist (mu_list_t list, struct list_data *current, @@ -53,6 +61,9 @@ extern void _mu_list_insert_sublist (mu_list_t list, struct list_data *tail, size_t count, int insert_before); +extern int _mu_list_insert_item (mu_list_t list, struct list_data *current, + void *new_item, + int insert_before); # ifdef __cplusplus } diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index 7c1c5c432..b32138250 100644 --- a/libmailutils/Makefile.am +++ b/libmailutils/Makefile.am @@ -16,8 +16,10 @@ # Public License along with this library. If not, see # <http://www.gnu.org/licenses/>. -SUBDIRS = auth base address sockaddr cidr cfg diag filter mailbox mailer mime\ - server string stream stdstream property url imapio . tests +SUBDIRS = \ + auth base address list sockaddr cidr cfg diag\ + filter mailbox mailer mime server string stream stdstream\ + property url imapio . tests lib_LTLIBRARIES = libmailutils.la @@ -34,6 +36,7 @@ libmailutils_la_LIBADD = \ diag/libdiag.la\ filter/libfilter.la\ imapio/libimapio.la\ + list/liblist.la\ mailbox/libmailbox.la\ mailer/libmailer.la\ mime/libmime.la\ diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am index 5f41b0c7a..cb6c52104 100644 --- a/libmailutils/base/Makefile.am +++ b/libmailutils/base/Makefile.am @@ -39,8 +39,6 @@ libbase_la_SOURCES = \ iterator.c\ kwd.c\ lcall.c\ - list.c\ - listlist.c\ locale.c\ locker.c\ mailcap.c\ diff --git a/libmailutils/base/list.c b/libmailutils/base/list.c deleted file mode 100644 index 74ec644b3..000000000 --- a/libmailutils/base/list.c +++ /dev/null @@ -1,705 +0,0 @@ -/* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010, 2011 - Free Software Foundation, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <mailutils/sys/list.h> -#include <mailutils/sys/iterator.h> -#include <mailutils/errno.h> - -#define DESTROY_ITEM(list, elt) \ - do \ - { \ - if ((list)->destroy_item) \ - (list)->destroy_item ((elt)->item); \ - } \ - while (0) - -int -mu_list_create (mu_list_t *plist) -{ - mu_list_t list; - int status; - - if (plist == NULL) - return MU_ERR_OUT_PTR_NULL; - list = calloc (sizeof (*list), 1); - if (list == NULL) - return ENOMEM; - status = mu_monitor_create (&list->monitor, 0, list); - if (status != 0) - { - free (list); - return status; - } - list->head.next = &list->head; - list->head.prev = &list->head; - *plist = list; - return 0; -} - -void -mu_list_clear (mu_list_t list) -{ - struct list_data *current; - struct list_data *previous; - - if (!list) - return; - mu_monitor_wrlock (list->monitor); - for (current = list->head.next; current != &list->head;) - { - previous = current; - current = current->next; - DESTROY_ITEM (list, previous); - free (previous); - } - list->head.next = list->head.prev = &list->head; - mu_monitor_unlock (list->monitor); -} - -void -mu_list_destroy (mu_list_t *plist) -{ - if (plist && *plist) - { - mu_list_t list = *plist; - mu_list_clear (list); - mu_monitor_destroy (&list->monitor, list); - free (list); - *plist = NULL; - } -} - -int -mu_list_append (mu_list_t list, void *item) -{ - struct list_data *ldata; - struct list_data *last; - - if (list == NULL) - return EINVAL; - last = list->head.prev; - ldata = calloc (sizeof (*ldata), 1); - if (ldata == NULL) - return ENOMEM; - ldata->item = item; - mu_monitor_wrlock (list->monitor); - ldata->next = &list->head; - ldata->prev = list->head.prev; - last->next = ldata; - list->head.prev = ldata; - list->count++; - mu_monitor_unlock (list->monitor); - return 0; -} - -int -mu_list_prepend (mu_list_t list, void *item) -{ - struct list_data *ldata; - struct list_data *first; - - if (list == NULL) - return EINVAL; - first = list->head.next; - ldata = calloc (sizeof (*ldata), 1); - if (ldata == NULL) - return ENOMEM; - ldata->item = item; - mu_monitor_wrlock (list->monitor); - ldata->prev = &list->head; - ldata->next = list->head.next; - first->prev = ldata; - list->head.next = ldata; - list->count++; - mu_monitor_unlock (list->monitor); - return 0; -} - -int -mu_list_is_empty (mu_list_t list) -{ - size_t n = 0; - - mu_list_count (list, &n); - return (n == 0); -} - -int -mu_list_count (mu_list_t list, size_t *pcount) -{ - if (list == NULL) - return EINVAL; - if (pcount == NULL) - return MU_ERR_OUT_PTR_NULL; - *pcount = list->count; - return 0; -} - -mu_list_comparator_t -mu_list_set_comparator (mu_list_t list, mu_list_comparator_t comp) -{ - mu_list_comparator_t old_comp; - - if (list == NULL) - return NULL; - old_comp = list->comp; - list->comp = comp; - return old_comp; -} - -int -mu_list_get_comparator (mu_list_t list, mu_list_comparator_t *comp) -{ - if (!list) - return EINVAL; - *comp = list->comp; - return 0; -} - -int -_mu_list_ptr_comparator (const void *item, const void *value) -{ - return item != value; -} - -int -mu_list_locate (mu_list_t list, void *item, void **ret_item) -{ - struct list_data *current, *previous; - mu_list_comparator_t comp; - int status = MU_ERR_NOENT; - - if (list == NULL) - return EINVAL; - comp = list->comp ? list->comp : _mu_list_ptr_comparator; - mu_monitor_wrlock (list->monitor); - for (previous = &list->head, current = list->head.next; - current != &list->head; previous = current, current = current->next) - { - if (comp (current->item, item) == 0) - { - if (ret_item) - *ret_item = current->item; - status = 0; - break; - } - } - mu_monitor_unlock (list->monitor); - return status; -} - -static int -_insert_item (mu_list_t list, struct list_data *current, void *new_item, - int insert_before) -{ - int status; - struct list_data *ldata = calloc (sizeof (*ldata), 1); - if (ldata == NULL) - status = ENOMEM; - else - { - ldata->item = new_item; - _mu_list_insert_sublist (list, current, - ldata, ldata, - 1, - insert_before); - status = 0; - } - return status; -} - -int -mu_list_insert (mu_list_t list, void *item, void *new_item, int insert_before) -{ - struct list_data *current; - mu_list_comparator_t comp; - int status = MU_ERR_NOENT; - - if (list == NULL) - return EINVAL; - comp = list->comp ? list->comp : _mu_list_ptr_comparator; - - mu_monitor_wrlock (list->monitor); - for (current = list->head.next; - current != &list->head; - current = current->next) - { - if (comp (current->item, item) == 0) - { - status = _insert_item (list, current, new_item, insert_before); - break; - } - } - mu_monitor_unlock (list->monitor); - return status; -} - -int -mu_list_remove (mu_list_t list, void *item) -{ - struct list_data *current; - mu_list_comparator_t comp; - int status = MU_ERR_NOENT; - - if (list == NULL) - return EINVAL; - comp = list->comp ? list->comp : _mu_list_ptr_comparator; - mu_monitor_wrlock (list->monitor); - for (current = list->head.next; - current != &list->head; current = current->next) - { - if (comp (current->item, item) == 0) - { - struct list_data *previous = current->prev; - - mu_iterator_advance (list->itr, current); - previous->next = current->next; - current->next->prev = previous; - DESTROY_ITEM (list, current); - free (current); - list->count--; - status = 0; - break; - } - } - mu_monitor_unlock (list->monitor); - return status; -} - -int -mu_list_remove_nd (mu_list_t list, void *item) -{ - mu_list_destroy_item_t dptr = mu_list_set_destroy_item (list, NULL); - int rc = mu_list_remove (list, item); - mu_list_set_destroy_item (list, dptr); - return rc; -} - -int -mu_list_replace (mu_list_t list, void *old_item, void *new_item) -{ - struct list_data *current, *previous; - mu_list_comparator_t comp; - int status = MU_ERR_NOENT; - - if (list == NULL) - return EINVAL; - comp = list->comp ? list->comp : _mu_list_ptr_comparator; - mu_monitor_wrlock (list->monitor); - for (previous = &list->head, current = list->head.next; - current != &list->head; previous = current, current = current->next) - { - if (comp (current->item, old_item) == 0) - { - DESTROY_ITEM (list, current); - current->item = new_item; - status = 0; - break; - } - } - mu_monitor_unlock (list->monitor); - return status; -} - -int -mu_list_replace_nd (mu_list_t list, void *item, void *new_item) -{ - mu_list_destroy_item_t dptr = mu_list_set_destroy_item (list, NULL); - int rc = mu_list_replace (list, item, new_item); - mu_list_set_destroy_item (list, dptr); - return rc; -} - -int -mu_list_get (mu_list_t list, size_t indx, void **pitem) -{ - struct list_data *current; - size_t count; - int status = MU_ERR_NOENT; - - if (list == NULL) - return EINVAL; - if (pitem == NULL) - return MU_ERR_OUT_PTR_NULL; - mu_monitor_rdlock (list->monitor); - for (current = list->head.next, count = 0; current != &list->head; - current = current->next, count++) - { - if (count == indx) - { - *pitem = current->item; - status = 0; - break; - } - } - mu_monitor_unlock (list->monitor); - return status; -} - -int -mu_list_do (mu_list_t list, mu_list_action_t *action, void *cbdata) -{ - mu_iterator_t itr; - int status = 0; - - if (list == NULL || action == NULL) - return EINVAL; - status = mu_list_get_iterator (list, &itr); - if (status) - return status; - for (mu_iterator_first (itr); !mu_iterator_is_done (itr); - mu_iterator_next (itr)) - { - void *item; - mu_iterator_current (itr, &item); - if ((status = action (item, cbdata))) - break; - } - mu_iterator_destroy (&itr); - return status; -} - -mu_list_destroy_item_t -mu_list_set_destroy_item (mu_list_t list, void (*destroy_item)(void *item)) -{ - mu_list_destroy_item_t ret = list->destroy_item; - list->destroy_item = destroy_item; - return ret; -} - -int -mu_list_to_array (mu_list_t list, void **array, size_t count, size_t *pcount) -{ - size_t total = 0; - - if (!list) - return EINVAL; - - total = (count < list->count) ? count : list->count; - - if (array) - { - size_t i; - struct list_data *current; - - for (i = 0, current = list->head.next; - i < total && current != &list->head; current = current->next) - array[i++] = current->item; - } - if (pcount) - *pcount = total; - return 0; -} - -/* Computes an intersection of two lists and returns it in PDEST. - The resulting list contains elements from A that are - also encountered in B (as per comparison function of - the latter). - - If DUP_ITEM is not NULL, it is used to create copies of - items to be stored in PDEST. In this case, the destroy_item - function of B is also attached to PDEST. Otherwise, if - DUP_ITEM is NULL, pointers to elements are stored and - no destroy_item function is assigned. */ -int -mu_list_intersect_dup (mu_list_t *pdest, mu_list_t a, mu_list_t b, - int (*dup_item) (void **, void *, void *), - void *dup_closure) -{ - mu_list_t dest; - int rc; - mu_iterator_t itr; - - rc = mu_list_create (&dest); - if (rc) - return rc; - - mu_list_set_comparator (dest, b->comp); - if (dup_item) - mu_list_set_destroy_item (dest, b->destroy_item); - - rc = mu_list_get_iterator (a, &itr); - if (rc) - { - mu_list_destroy (&dest); - return rc; - } - - rc = 0; - for (mu_iterator_first (itr); !mu_iterator_is_done (itr); - mu_iterator_next (itr)) - { - void *data; - mu_iterator_current (itr, &data); - if (mu_list_locate (b, data, NULL) == 0) - { - void *new_data; - if (dup_item && data) - { - rc = dup_item (&new_data, data, dup_closure); - if (rc) - break; - } - else - new_data = data; - - mu_list_append (dest, new_data); /* FIXME: Check return, and? */ - } - } - mu_iterator_destroy (&itr); - *pdest = dest; - return rc; -} - -int -mu_list_intersect (mu_list_t *pdest, mu_list_t a, mu_list_t b) -{ - return mu_list_intersect_dup (pdest, a, b, NULL, NULL); -} - - -/* Iterator interface */ - -struct list_iterator -{ - mu_list_t list; - struct list_data *cur; - int backwards; /* true if iterating backwards */ -}; - -static int -first (void *owner) -{ - struct list_iterator *itr = owner; - if (itr->backwards) - itr->cur = itr->list->head.prev; - else - itr->cur = itr->list->head.next; - return 0; -} - -static int -next (void *owner) -{ - struct list_iterator *itr = owner; - if (itr->backwards) - itr->cur = itr->cur->prev; - else - itr->cur = itr->cur->next; - return 0; -} - -static int -getitem (void *owner, void **pret, const void **pkey) -{ - struct list_iterator *itr = owner; - *pret = itr->cur->item; - if (pkey) - *pkey = NULL; - return 0; -} - -static int -finished_p (void *owner) -{ - struct list_iterator *itr = owner; - return itr->cur == &itr->list->head; -} - -static int -destroy (mu_iterator_t iterator, void *data) -{ - struct list_iterator *itr = data; - mu_iterator_detach (&itr->list->itr, iterator); - free (data); - return 0; -} - -static int -curitem_p (void *owner, void *item) -{ - struct list_iterator *itr = owner; - return itr->cur == item; -} - -static int -list_data_dup (void **ptr, void *owner) -{ - *ptr = malloc (sizeof (struct list_iterator)); - if (*ptr == NULL) - return ENOMEM; - memcpy (*ptr, owner, sizeof (struct list_iterator)); - return 0; -} - -static int -list_itrctl (void *owner, enum mu_itrctl_req req, void *arg) -{ - struct list_iterator *itr = owner; - mu_list_t list = itr->list; - struct list_data *ptr; - - switch (req) - { - case mu_itrctl_tell: - /* Return current position in the object */ - if (itr->cur == NULL) - return MU_ERR_NOENT; - else - { - size_t count; - - for (count = 0, ptr = list->head.next; ptr != &list->head; - ptr = ptr->next, count++) - { - if (ptr == itr->cur) - { - *(size_t*)arg = count; - return 0; - } - } - return MU_ERR_NOENT; - } - break; - - case mu_itrctl_delete: - case mu_itrctl_delete_nd: - /* Delete current element */ - if (itr->cur == NULL) - return MU_ERR_NOENT; - else - { - struct list_data *prev; - - ptr = itr->cur; - prev = ptr->prev; - - mu_iterator_advance (list->itr, ptr); - prev->next = ptr->next; - ptr->next->prev = prev; - if (req == mu_itrctl_delete) - DESTROY_ITEM (list, ptr); - free (ptr); - list->count--; - } - break; - - case mu_itrctl_replace: - case mu_itrctl_replace_nd: - /* Replace current element */ - if (itr->cur == NULL) - return MU_ERR_NOENT; - if (!arg) - return EINVAL; - ptr = itr->cur; - if (req == mu_itrctl_replace) - DESTROY_ITEM (list, ptr); - ptr = itr->cur; - ptr->item = arg; - break; - - case mu_itrctl_insert: - /* Insert new element in the current position */ - if (itr->cur == NULL) - return MU_ERR_NOENT; - if (!arg) - return EINVAL; - return _insert_item (list, itr->cur, arg, 0); - - case mu_itrctl_insert_list: - /* Insert a list of elements */ - if (itr->cur == NULL) - return MU_ERR_NOENT; - if (!arg) - return EINVAL; - else - { - mu_list_t new_list = arg; - _mu_list_insert_sublist (list, itr->cur, - new_list->head.next, new_list->head.prev, - new_list->count, - 0); - _mu_list_clear (new_list); - } - break; - - case mu_itrctl_qry_direction: - if (!arg) - return EINVAL; - else - *(int*)arg = itr->backwards; - break; - - case mu_itrctl_set_direction: - if (!arg) - return EINVAL; - else - itr->backwards = !!*(int*)arg; - break; - - default: - return ENOSYS; - } - return 0; -} - -int -mu_list_get_iterator (mu_list_t list, mu_iterator_t *piterator) -{ - mu_iterator_t iterator; - int status; - struct list_iterator *itr; - - if (!list) - return EINVAL; - - itr = calloc (1, sizeof *itr); - if (!itr) - return ENOMEM; - itr->list = list; - itr->cur = NULL; - - status = mu_iterator_create (&iterator, itr); - if (status) - { - free (itr); - return status; - } - - mu_iterator_set_first (iterator, first); - mu_iterator_set_next (iterator, next); - mu_iterator_set_getitem (iterator, getitem); - mu_iterator_set_finished_p (iterator, finished_p); - mu_iterator_set_curitem_p (iterator, curitem_p); - mu_iterator_set_destroy (iterator, destroy); - mu_iterator_set_dup (iterator, list_data_dup); - mu_iterator_set_itrctl (iterator, list_itrctl); - - mu_iterator_attach (&list->itr, iterator); - - *piterator = iterator; - return 0; -} diff --git a/libmailutils/list/Makefile.am b/libmailutils/list/Makefile.am new file mode 100644 index 000000000..e6d77cd22 --- /dev/null +++ b/libmailutils/list/Makefile.am @@ -0,0 +1,43 @@ +# GNU Mailutils -- a suite of utilities for electronic mail +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library. If not, see +# <http://www.gnu.org/licenses/>. + +noinst_LTLIBRARIES = liblist.la + +liblist_la_SOURCES = \ + append.c\ + array.c\ + clear.c\ + count.c\ + create.c\ + destroy.c\ + do.c\ + empty.c\ + get.c\ + getcomp.c\ + insert.c\ + intersect.c\ + iterator.c\ + listlist.c\ + locate.c\ + prepend.c\ + remove.c\ + replace.c\ + setcomp.c\ + setdestr.c + +INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils + diff --git a/libmailutils/list/append.c b/libmailutils/list/append.c new file mode 100644 index 000000000..f514b3f09 --- /dev/null +++ b/libmailutils/list/append.c @@ -0,0 +1,47 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010, 2011 + Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <mailutils/sys/list.h> +#include <mailutils/errno.h> + +int +mu_list_append (mu_list_t list, void *item) +{ + struct list_data *ldata; + struct list_data *last; + + if (list == NULL) + return EINVAL; + last = list->head.prev; + ldata = calloc (sizeof (*ldata), 1); + if (ldata == NULL) + return ENOMEM; + ldata->item = item; + mu_monitor_wrlock (list->monitor); + ldata->next = &list->head; + ldata->prev = list->head.prev; + last->next = ldata; + list->head.prev = ldata; + list->count++; + mu_monitor_unlock (list->monitor); + return 0; +} diff --git a/libmailutils/list/array.c b/libmailutils/list/array.c new file mode 100644 index 000000000..65433afdb --- /dev/null +++ b/libmailutils/list/array.c @@ -0,0 +1,48 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010, 2011 + Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <mailutils/sys/list.h> +#include <mailutils/errno.h> + +int +mu_list_to_array (mu_list_t list, void **array, size_t count, size_t *pcount) +{ + size_t total = 0; + + if (!list) + return EINVAL; + + total = (count < list->count) ? count : list->count; + + if (array) + { + size_t i; + struct list_data *current; + + for (i = 0, current = list->head.next; + i < total && current != &list->head; current = current->next) + array[i++] = current->item; + } + if (pcount) + *pcount = total; + return 0; +} + diff --git a/libmailutils/list/clear.c b/libmailutils/list/clear.c new file mode 100644 index 000000000..e39b38945 --- /dev/null +++ b/libmailutils/list/clear.c @@ -0,0 +1,43 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010, 2011 + Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <mailutils/sys/list.h> + +void +mu_list_clear (mu_list_t list) +{ + struct list_data *current; + struct list_data *previous; + + if (!list) + return; + mu_monitor_wrlock (list->monitor); + for (current = list->head.next; current != &list->head;) + { + previous = current; + current = current->next; + DESTROY_ITEM (list, previous); + free (previous); + } + list->head.next = list->head.prev = &list->head; + mu_monitor_unlock (list->monitor); +} diff --git a/libmailutils/list/count.c b/libmailutils/list/count.c new file mode 100644 index 000000000..981dbcc2e --- /dev/null +++ b/libmailutils/list/count.c @@ -0,0 +1,35 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010, 2011 + Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + |