/* Based on gslist.c from glib-1.2.9 (LGPL). Adaption to JACK, Copyright (C) 2002 Kai Vehmanen. - replaced use of gtypes with normal ANSI C types - glib's memery allocation routines replaced with malloc/free calls This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser Lesser General Public License for more details. You should have received a copy of the GNU Lesser Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: list.h,v 1.1.1.1 2003/10/13 22:53:27 rah Exp $ */ /* * Nicked from jack, with: * s/jack_slist/cca_list/g * s/JSList/cca_list_t/g * s/malloc/cca_malloc/g * - Bob Ham */ #ifndef __LADCCA_LIST_H__ #define __LADCCA_LIST_H__ #include <ladcca/xmalloc.h> #ifdef __cplusplus extern "C" { #endif typedef struct _cca_list cca_list_t; typedef int (*JCompareFunc) (void* a, void* b); struct _cca_list { void *data; cca_list_t *next; }; static __inline__ cca_list_t* cca_list_alloc (void) { cca_list_t *new_list; new_list = (cca_list_t *) cca_malloc(sizeof(cca_list_t)); new_list->data = NULL; new_list->next = NULL; return new_list; } static __inline__ cca_list_t* cca_list_prepend (cca_list_t *list, void *data) { cca_list_t *new_list; new_list = (cca_list_t *) cca_malloc(sizeof(cca_list_t)); new_list->data = data; new_list->next = list; return new_list; } #define cca_list_next(slist) ((slist) ? (((cca_list_t *)(slist))->next) : NULL) static __inline__ cca_list_t* cca_list_last (cca_list_t *list) { if (list) { while (list->next) list = list->next; } return list; } static __inline__ cca_list_t* cca_list_remove_link (cca_list_t *list, cca_list_t *link) { cca_list_t *tmp; cca_list_t *prev; prev = NULL; tmp = list; while (tmp) { if (tmp == link) { if (prev) prev->next = tmp->next; if (list == tmp) list = list->next; tmp->next = NULL; break; } prev = tmp; tmp = tmp->next; } return list; } static __inline__ void cca_list_free (cca_list_t *list) { while (list) { cca_list_t *next = list->next; free(list); list = next; } } static __inline__ void cca_list_free_1 (cca_list_t *list) { if (list) { free(list); } } static __inline__ cca_list_t* cca_list_remove (cca_list_t *list, void *data) { cca_list_t *tmp; cca_list_t *prev; prev = NULL; tmp = list; while (tmp) { if (tmp->data == data) { if (prev) prev->next = tmp->next; if (list == tmp) list = list->next; tmp->next = NULL; cca_list_free (tmp); break; } prev = tmp; tmp = tmp->next; } return list; } static __inline__ unsigned int cca_list_length (cca_list_t *list) { unsigned int length; length = 0; while (list) { length++; list = list->next; } return length; } static __inline__ cca_list_t* cca_list_find (cca_list_t *list, void *data) { while (list) { if (list->data == data) break; list = list->next; } return list; } static __inline__ cca_list_t* cca_list_copy (cca_list_t *list) { cca_list_t *new_list = NULL; if (list) { cca_list_t *last; new_list = cca_list_alloc (); new_list->data = list->data; last = new_list; list = list->next; while (list) { last->next = cca_list_alloc (); last = last->next; last->data = list->data; list = list->next; } } return new_list; } static __inline__ cca_list_t* cca_list_append (cca_list_t *list, void *data) { cca_list_t *new_list; cca_list_t *last; new_list = cca_list_alloc (); new_list->data = data; if (list) { last = cca_list_last (list); last->next = new_list; return list; } else return new_list; } static __inline__ cca_list_t* cca_list_sort_merge (cca_list_t *l1, cca_list_t *l2, JCompareFunc compare_func) { cca_list_t list, *l; l=&list; while (l1 && l2) { if (compare_func(l1->data,l2->data) < 0) { l=l->next=l1; l1=l1->next; } else { l=l->next=l2; l2=l2->next; } } l->next= l1 ? l1 : l2; return list.next; } static __inline__ cca_list_t* cca_list_sort (cca_list_t *list, JCompareFunc compare_func) { cca_list_t *l1, *l2; if (!list) return NULL; if (!list->next) return list; l1 = list; l2 = list->next; while ((l2 = l2->next) != NULL) { if ((l2 = l2->next) == NULL) break; l1=l1->next; } l2 = l1->next; l1->next = NULL; return cca_list_sort_merge (cca_list_sort (list, compare_func), cca_list_sort (l2, compare_func), compare_func); } static __inline__ cca_list_t * cca_list_concat (cca_list_t *list1, cca_list_t *list2) { if (list2) { if (list1) cca_list_last (list1)->next = list2; else list1 = list2; } return list1; } #ifdef __cplusplus } #endif #endif /* __LADCCA_LIST_H__ */