]> git.sesse.net Git - vlc/blob - modules/codec/cmml/xlist.c
macosx: Ask to send a mail to our bugreport ML if a crash log is detected.
[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 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdlib.h>
32
33 #include "xlist.h"
34
35 static XList *
36 xlist_node_new (void * data)
37 {
38   XList * l;
39
40   l = (XList *) malloc (sizeof (XList));
41   l->prev = l->next = NULL;
42   l->data = data;
43
44   return l;
45 }
46
47 XList *
48 xlist_new (void)
49 {
50   return NULL;
51 }
52
53 XList *
54 xlist_clone (XList * list)
55 {
56   XList * l, * new_list;
57
58   if (list == NULL) return NULL;
59   new_list = xlist_new ();
60
61   for (l = list; l; l = l->next) {
62     new_list = xlist_append (new_list, l->data);
63   }
64
65   return new_list;
66 }
67
68 XList *
69 xlist_clone_with (XList * list, XCloneFunc clone)
70 {
71   XList * l, * new_list;
72   void * new_data;
73
74   if (list == NULL) return NULL;
75   if (clone == NULL) return xlist_clone (list);
76
77   new_list = xlist_new ();
78
79   for (l = list; l; l = l->next) {
80     new_data = clone (l->data);
81     new_list = xlist_append (new_list, new_data);
82   }
83
84   return new_list;
85 }
86
87
88 XList *
89 xlist_tail (XList * list)
90 {
91   XList * l;
92   for (l = list; l; l = l->next)
93     if (l->next == NULL) return l;
94   return NULL;
95 }
96
97 XList *
98 xlist_prepend (XList * list, void * data)
99 {
100   XList * l = xlist_node_new (data);
101
102   if (list == NULL) return l;
103
104   l->next = list;
105   list->prev = l;
106
107   return l;
108 }
109
110 XList *
111 xlist_append (XList * list, void * data)
112 {
113   XList * l = xlist_node_new (data);
114   XList * last;
115
116   if (list == NULL) return l;
117
118   last = xlist_tail (list);
119   if (last) last->next = l;
120   l->prev = last;
121   return list;
122 }
123
124 XList *
125 xlist_add_before (XList * list, void * data, XList * node)
126 {
127   XList * l, * p;
128
129   if (list == NULL) return xlist_node_new (data);
130   if (node == NULL) return xlist_append (list, data);
131   if (node == list) return xlist_prepend (list, data);
132
133   l = xlist_node_new (data);
134   p = node->prev;
135
136   l->prev = p;
137   l->next = node;
138   if (p) p->next = l;
139   node->prev = l;
140  
141   return list;
142 }
143
144 XList *
145 xlist_add_after (XList * list, void * data, XList * node)
146 {
147   XList * l, * n;
148
149   if (node == NULL) return xlist_prepend (list, data);
150
151   l = xlist_node_new (data);
152   n = node->next;
153
154   l->prev = node;
155   l->next = n;
156   if (n) n->prev = l;
157   node->next = l;
158
159   return list;
160 }
161
162 XList *
163 xlist_find (XList * list, void * data)
164 {
165   XList * l;
166
167   for (l = list; l; l = l->next)
168     if (l->data == data) return l;
169
170   return NULL;
171 }
172
173 XList *
174 xlist_remove (XList * list, XList * node)
175 {
176   if (node == NULL) return list;
177
178   if (node->prev) node->prev->next = node->next;
179   if (node->next) node->next->prev = node->prev;
180
181   if (node == list) return list->next;
182   else return list;
183 }
184
185 int
186 xlist_length (XList * list)
187 {
188   XList * l;
189   int c = 0;
190
191   for (l = list; l; l = l->next)
192     c++;
193
194   return c;
195 }
196
197 int
198 xlist_is_empty (XList * list)
199 {
200   return (list == NULL);
201 }
202
203 int
204 xlist_is_singleton (XList * list)
205 {
206   if (list == NULL) return 0;
207   if (list->next == NULL) return 1;
208   else return 0;
209 }
210
211 /*
212  * xlist_free_with (list, free_func)
213  *
214  * Step through list 'list', freeing each node using free_func(), and
215  * also free the list structure itself.
216  */
217 XList *
218 xlist_free_with (XList * list, XFreeFunc free_func)
219 {
220   XList * l, * ln;
221
222   for (l = list; l; l = ln) {
223     ln = l->next;
224     free_func (l->data);
225     free (l);
226   }
227
228   return NULL;
229 }
230
231 /*
232  * xlist_free (list)
233  *
234  * Free the list structure 'list', but not its nodes.
235  */
236 XList *
237 xlist_free (XList * list)
238 {
239   XList * l, * ln;
240
241   for (l = list; l; l = ln) {
242     ln = l->next;
243     free (l);
244   }
245
246   return NULL;
247 }
248