/*
Copyright (C) 1999-2004 IC & S dbmail@ic-s.nl
Copyright (c) 2004-2006 NFG Net Facilities Group BV support@nfg.nl
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: list.c 2141 2006-06-02 14:40:22Z aaron $
*
* functions to create lists and add/delete items */
#include "dbmail.h"
void dm_list_init(struct dm_list *tlist)
{
memset(tlist,'\0', sizeof(struct dm_list));
}
/*
* dm_list_free()
*
* frees a list and all the memory associated with it
*/
void dm_list_free(struct element **start)
{
if (!start || !(*start))
return;
if (!(*start))
return;
dm_list_free(&(*start)->nextnode);
/* free this item */
g_free((*start)->data);
g_free(*start);
*start = NULL;
}
/*
* dm_list_reverse()
*
* reverse the order of a linked list
*/
struct element *dm_list_reverse(struct element *start)
{
struct element *newstart;
if (!start)
return NULL; /* nothing there */
if (!start->nextnode)
return start; /* nothing to reverse */
newstart = dm_list_reverse(start->nextnode); /* reverse rest of list */
start->nextnode->nextnode = start;
start->nextnode = NULL; /* terminate list */
return newstart;
}
/*
* return a empty initialized element;
*/
static struct element *element_new(void)
{
return g_new0(struct element,1);
}
/*
* dm_list_nodeadd()
*
* Adds a node to a linked list (list structure).
* New item will be FIRST element of new linked list.
*
* returns NULL on failure or first element on success
*/
struct element *dm_list_nodeadd(struct dm_list *tlist, const void *data,
size_t dsize)
{
struct element *p;
if (!tlist)
return NULL; /* cannot add to non-existing list */
if (! (p = element_new()))
return NULL;
if (! (p->data = (void *)g_malloc0(dsize))) {
g_free(p);
return NULL;
}
p->data = memcpy(p->data, data, dsize);
p->dsize=dsize;
p->nextnode=tlist->start;
tlist->start = p;
/* updating node count */
tlist->total_nodes++;
return tlist->start;
}
struct element *dm_list_getstart(struct dm_list *tlist)
{
return (tlist) ? tlist->start : NULL;
}
long dm_list_length(struct dm_list *tlist)
{
return (tlist) ? tlist->total_nodes : -1; /* a NULL ptr doesnt even have zero nodes (?) */
}
/*
* shallow copy of struct dm_list into GList
*/
GList * g_list_copy_list(GList *dst, struct element *el)
{
while(el) {
dst = g_list_append(dst, el->data);
el = el->nextnode;
}
return dst;
}
/*
* return a list of strings (a,b,c,..N)
*/
GList *g_list_slices(GList *list, unsigned limit)
{
unsigned i,j;
GList *new = NULL;
GString *slice;
if (g_list_length(list) <= limit) {
slice = g_list_join(list,",");
new=g_list_append(new,g_strdup(slice->str));
g_string_free(slice,TRUE);
return new;
}
j = g_list_length(list) % limit;
list = g_list_first(list);
while(list) {
slice = g_string_new("");
slice = g_string_append(slice, (gchar *)list->data);
for (i=1; i<limit; i++) {
if (! g_list_next(list))
break;
list = g_list_next(list);
slice = g_string_append(slice,",");
slice = g_string_append(slice,(gchar *)list->data);
}
new = g_list_append(new, g_strdup(slice->str));
g_string_free(slice,TRUE);
if (! g_list_next(list))
break;
list = g_list_next(list);
}
return new;
}
syntax highlighted by Code2HTML, v. 0.9.1