Commit db7e58b4 db7e58b41501fda7629080195e33946f6d26e2a3 by Sergey Poznyakoff

Move list support into a separate convenience library.

* configure.ac: Build libmailutils/list/Makefile
* include/mailutils/sys/list.h (DESTROY_ITEM): New define.
(_mu_list_insert_item): New proto.
* libmailutils/Makefile.am (SUBDIRS): Add list.
(libmailutils_la_LIBADD): Add list/liblist.la
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Remove list sources.
* libmailutils/base/list.c: Split into smaller files (see below).
* libmailutils/base/listlist.c: Move to libmailutils/list/listlist.c
* libmailutils/list/Makefile.am: New file.
* libmailutils/list/append.c: New file.
* libmailutils/list/array.c: New file.
* libmailutils/list/clear.c: New file.
* libmailutils/list/count.c: New file.
* libmailutils/list/create.c: New file.
* libmailutils/list/destroy.c: New file.
* libmailutils/list/do.c: New file.
* libmailutils/list/empty.c: New file.
* libmailutils/list/get.c: New file.
* libmailutils/list/getcomp.c: New file.
* libmailutils/list/insert.c: New file.
* libmailutils/list/intersect.c: New file.
* libmailutils/list/iterator.c: New file.
* libmailutils/list/locate.c: New file.
* libmailutils/list/prepend.c: New file.
* libmailutils/list/remove.c: New file.
* libmailutils/list/replace.c: New file.
* libmailutils/list/setcomp.c: New file.
* libmailutils/list/setdestr.c: New file.
1 parent f7942ced
......@@ -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
......
......@@ -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
}
......
......@@ -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\
......
......@@ -39,8 +39,6 @@ libbase_la_SOURCES = \
iterator.c\
kwd.c\
lcall.c\
list.c\
listlist.c\
locale.c\
locker.c\
mailcap.c\
......
# 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
/* 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;
}
/* 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;
}
/* 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);
}
/* 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_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;
}
/* 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_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;
}
/* 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_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;
}
}
/* 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_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;
}
/* 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>
int
mu_list_is_empty (mu_list_t list)
{
size_t n = 0;
mu_list_count (list, &n);
return (n == 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 <stdlib.h>
#include <mailutils/sys/list.h>
#include <mailutils/errno.h>
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;
}
/* 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_get_comparator (mu_list_t list, mu_list_comparator_t *comp)
{
if (!list)
return EINVAL;
*comp = list->comp;
return 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 <stdlib.h>
#include <mailutils/sys/list.h>
#include <mailutils/errno.h>
int
_mu_list_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 = _mu_list_insert_item (list, current, new_item,
insert_before);
break;
}
}
mu_monitor_unlock (list->monitor);
return status;
}
/* 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>
/* 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);
}
/* 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 <string.h>
#include <mailutils/sys/list.h>
#include <mailutils/sys/iterator.h>
#include <mailutils/errno.h>
/* 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 _mu_list_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;
}
......@@ -19,11 +19,7 @@
#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>
......
/* 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_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;
}
/* 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_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;
}
/* 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_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;
}
/* 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_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;
}
/* 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>
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;
}
/* 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>
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;
}