]> git.sesse.net Git - vlc/blob - modules/codec/cmml/xlist.c
Remove stdlib.h
[vlc] / modules / codec / cmml / xlist.c
1 /*****************************************************************************
2  * xlist.c : a simple doubly linked list in C
3  *****************************************************************************
4  * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
5  *                         Organisation (CSIRO) Australia
6  * Copyright (C) 2000-2004 the VideoLAN team
7  *
8  * $Id$
9  *
10  * Authors: Conrad Parker <Conrad.Parker@csiro.au>
11  *          Andre Pang <Andre.Pang@csiro.au>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28
29 #include "xlist.h"
30
31 static XList *
32 xlist_node_new (void * data)
33 {
34   XList * l;
35
36   l = (XList *) malloc (sizeof (XList));
37   l->prev = l->next = NULL;
38   l->data = data;
39
40   return l;
41 }
42
43 XList *
44 xlist_new (void)
45 {
46   return NULL;
47 }
48
49 XList *
50 xlist_clone (XList * list)
51 {
52   XList * l, * new_list;
53
54   if (list == NULL) return NULL;
55   new_list = xlist_new ();
56
57   for (l = list; l; l = l->next) {
58     new_list = xlist_append (new_list, l->data);
59   }
60
61   return new_list;
62 }
63
64 XList *
65 xlist_clone_with (XList * list, XCloneFunc clone)
66 {
67   XList * l, * new_list;
68   void * new_data;
69
70   if (list == NULL) return NULL;
71   if (clone == NULL) return xlist_clone (list);
72
73   new_list = xlist_new ();
74
75   for (l = list; l; l = l->next) {
76     new_data = clone (l->data);
77     new_list = xlist_append (new_list, new_data);
78   }
79
80   return new_list;
81 }
82
83
84 XList *
85 xlist_tail (XList * list)
86 {
87   XList * l;
88   for (l = list; l; l = l->next)
89     if (l->next == NULL) return l;
90   return NULL;
91 }
92
93 XList *
94 xlist_prepend (XList * list, void * data)
95 {
96   XList * l = xlist_node_new (data);
97
98   if (list == NULL) return l;
99
100   l->next = list;
101   list->prev = l;
102
103   return l;
104 }
105
106 XList *
107 xlist_append (XList * list, void * data)
108 {
109   XList * l = xlist_node_new (data);
110   XList * last;
111
112   if (list == NULL) return l;
113
114   last = xlist_tail (list);
115   if (last) last->next = l;
116   l->prev = last; 
117   return list;
118 }
119
120 XList *
121 xlist_add_before (XList * list, void * data, XList * node)
122 {
123   XList * l, * p;
124
125   if (list == NULL) return xlist_node_new (data);
126   if (node == NULL) return xlist_append (list, data);
127   if (node == list) return xlist_prepend (list, data);
128
129   l = xlist_node_new (data);
130   p = node->prev;
131
132   l->prev = p;
133   l->next = node;
134   if (p) p->next = l;
135   node->prev = l;
136   
137   return list;
138 }
139
140 XList *
141 xlist_add_after (XList * list, void * data, XList * node)
142 {
143   XList * l, * n;
144
145   if (node == NULL) return xlist_prepend (list, data);
146
147   l = xlist_node_new (data);
148   n = node->next;
149
150   l->prev = node;
151   l->next = n;
152   if (n) n->prev = l;
153   node->next = l;
154
155   return list;
156 }
157
158 XList *
159 xlist_find (XList * list, void * data)
160 {
161   XList * l;
162
163   for (l = list; l; l = l->next)
164     if (l->data == data) return l;
165
166   return NULL;
167 }
168
169 XList *
170 xlist_remove (XList * list, XList * node)
171 {
172   if (node == NULL) return list;
173
174   if (node->prev) node->prev->next = node->next;
175   if (node->next) node->next->prev = node->prev;
176
177   if (node == list) return list->next;
178   else return list;
179 }
180
181 int
182 xlist_length (XList * list)
183 {
184   XList * l;
185   int c = 0;
186
187   for (l = list; l; l = l->next)
188     c++;
189
190   return c;
191 }
192
193 int
194 xlist_is_empty (XList * list)
195 {
196   return (list == NULL);
197 }
198
199 int
200 xlist_is_singleton (XList * list)
201 {
202   if (list == NULL) return 0;
203   if (list->next == NULL) return 1;
204   else return 0;
205 }
206
207 /*
208  * xlist_free_with (list, free_func)
209  *
210  * Step through list 'list', freeing each node using free_func(), and
211  * also free the list structure itself.
212  */
213 XList *
214 xlist_free_with (XList * list, XFreeFunc free_func)
215 {
216   XList * l, * ln;
217
218   for (l = list; l; l = ln) {
219     ln = l->next;
220     free_func (l->data);
221     free (l);
222   }
223
224   return NULL;
225 }
226
227 /*
228  * xlist_free (list)
229  *
230  * Free the list structure 'list', but not its nodes.
231  */
232 XList *
233 xlist_free (XList * list)
234 {
235   XList * l, * ln;
236
237   for (l = list; l; l = ln) {
238     ln = l->next;
239     free (l);
240   }
241
242   return NULL;
243 }
244