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