1 /* $Id: llist.h 295 2005-12-16 19:44:24Z tsaviran $
2  * -------------------------------------------------------
3  * Copyright (C) 2002-2005 Tommi Saviranta <wnd@iki.fi>
4  *	(C) 2002 Lee Hardy <lee@leeh.co.uk>
5  * -------------------------------------------------------
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 
17 
18 #ifndef LLIST_H_
19 #define LLIST_H_
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif /* ifdef HAVE_CONFIG_H */
23 
24 
25 
26 typedef struct _llist_node llist_node;
27 typedef struct _llist_list llist_list;
28 
29 struct _llist_node
30 {
31 	void		*data;
32 	llist_node	*next;
33 	llist_node	*prev;
34 };
35 
36 struct _llist_list
37 {
38 	llist_node	*head;
39 	llist_node	*tail;
40 };
41 
42 llist_node *llist_create(void *data);
43 
44 void llist_add(llist_node *node, llist_list *list);
45 void llist_add_tail(llist_node *node, llist_list *list);
46 void llist_delete(llist_node *node, llist_list *list);
47 llist_node *llist_find(void *data, llist_list *list);
48 llist_node **llist_get_indexed(const llist_list *list);
49 
50 #define LLIST_EMPTY(firstnode, list) \
51 { \
52 	llist_node	*node = (firstnode); \
53 	llist_node	*nextnode; \
54 	while (node != NULL) { \
55 		nextnode = node->next; \
56 		xfree(node->data); \
57 		llist_delete(node, (list)); \
58 		node = nextnode; \
59 	} \
60 }
61 
62 
63 
64 /*
65  * Following macros can be used to walk thru the list even when elements
66  * will be removed during it.
67  *
68  * Example:
69  * LLIST_WALK_H(nicknames.nicks.head, char *);
70  * xfree(data);
71  * LLIST_WALK_F;
72  *
73  * Using these macros, "node" points to current node and "data" to node->data.
74  */
75 #define LLIST_WALK_H(firstitem, datatype) { \
76 	datatype	data; \
77 	llist_node	*node; \
78 	llist_node	*nextnode; \
79 	node = (firstitem); \
80 	while (node != NULL) { \
81 		nextnode = node->next; \
82 		data = (datatype) node->data;
83 #define LLIST_WALK_F \
84 		node = nextnode; \
85 	} }
86 #define LLIST_WALK_CONTINUE \
87 		node = nextnode; \
88 		continue;
89 /* Setting nextnode to NULL is just a pre-caution. */
90 #define LLIST_WALK_BREAK \
91 		nextnode = NULL; \
92 		break;
93 
94 
95 
96 /*
97  * Not worth the trouble (bytes) to do this:
98 void llist_empty(llist_list *list, void (* action) (void *));
99 */
100 
101 
102 #endif /* LLIST_H_ */
103