Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

xlist.c

00001 /*****************************************************************************
00002  * xlist.c : a simple doubly linked list in C
00003  *****************************************************************************
00004  * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
00005  *                         Organisation (CSIRO) Australia
00006  * Copyright (C) 2000-2004 the VideoLAN team
00007  *
00008  * $Id: xlist.c 11664 2005-07-09 06:17:09Z courmisch $
00009  *
00010  * Authors: Conrad Parker <[email protected]>
00011  *          Andre Pang <[email protected]>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00026  *****************************************************************************/
00027 
00028 #include <stdlib.h>
00029 
00030 #include "xlist.h"
00031 
00032 static XList *
00033 xlist_node_new (void * data)
00034 {
00035   XList * l;
00036 
00037   l = (XList *) malloc (sizeof (XList));
00038   l->prev = l->next = NULL;
00039   l->data = data;
00040 
00041   return l;
00042 }
00043 
00044 XList *
00045 xlist_new (void)
00046 {
00047   return NULL;
00048 }
00049 
00050 XList *
00051 xlist_clone (XList * list)
00052 {
00053   XList * l, * new_list;
00054 
00055   if (list == NULL) return NULL;
00056   new_list = xlist_new ();
00057 
00058   for (l = list; l; l = l->next) {
00059     new_list = xlist_append (new_list, l->data);
00060   }
00061 
00062   return new_list;
00063 }
00064 
00065 XList *
00066 xlist_clone_with (XList * list, XCloneFunc clone)
00067 {
00068   XList * l, * new_list;
00069   void * new_data;
00070 
00071   if (list == NULL) return NULL;
00072   if (clone == NULL) return xlist_clone (list);
00073 
00074   new_list = xlist_new ();
00075 
00076   for (l = list; l; l = l->next) {
00077     new_data = clone (l->data);
00078     new_list = xlist_append (new_list, new_data);
00079   }
00080 
00081   return new_list;
00082 }
00083 
00084 
00085 XList *
00086 xlist_tail (XList * list)
00087 {
00088   XList * l;
00089   for (l = list; l; l = l->next)
00090     if (l->next == NULL) return l;
00091   return NULL;
00092 }
00093 
00094 XList *
00095 xlist_prepend (XList * list, void * data)
00096 {
00097   XList * l = xlist_node_new (data);
00098 
00099   if (list == NULL) return l;
00100 
00101   l->next = list;
00102   list->prev = l;
00103 
00104   return l;
00105 }
00106 
00107 XList *
00108 xlist_append (XList * list, void * data)
00109 {
00110   XList * l = xlist_node_new (data);
00111   XList * last;
00112 
00113   if (list == NULL) return l;
00114 
00115   last = xlist_tail (list);
00116   if (last) last->next = l;
00117   l->prev = last; 
00118   return list;
00119 }
00120 
00121 XList *
00122 xlist_add_before (XList * list, void * data, XList * node)
00123 {
00124   XList * l, * p;
00125 
00126   if (list == NULL) return xlist_node_new (data);
00127   if (node == NULL) return xlist_append (list, data);
00128   if (node == list) return xlist_prepend (list, data);
00129 
00130   l = xlist_node_new (data);
00131   p = node->prev;
00132 
00133   l->prev = p;
00134   l->next = node;
00135   if (p) p->next = l;
00136   node->prev = l;
00137   
00138   return list;
00139 }
00140 
00141 XList *
00142 xlist_add_after (XList * list, void * data, XList * node)
00143 {
00144   XList * l, * n;
00145 
00146   if (node == NULL) return xlist_prepend (list, data);
00147 
00148   l = xlist_node_new (data);
00149   n = node->next;
00150 
00151   l->prev = node;
00152   l->next = n;
00153   if (n) n->prev = l;
00154   node->next = l;
00155 
00156   return list;
00157 }
00158 
00159 XList *
00160 xlist_find (XList * list, void * data)
00161 {
00162   XList * l;
00163 
00164   for (l = list; l; l = l->next)
00165     if (l->data == data) return l;
00166 
00167   return NULL;
00168 }
00169 
00170 XList *
00171 xlist_remove (XList * list, XList * node)
00172 {
00173   if (node == NULL) return list;
00174 
00175   if (node->prev) node->prev->next = node->next;
00176   if (node->next) node->next->prev = node->prev;
00177 
00178   if (node == list) return list->next;
00179   else return list;
00180 }
00181 
00182 int
00183 xlist_length (XList * list)
00184 {
00185   XList * l;
00186   int c = 0;
00187 
00188   for (l = list; l; l = l->next)
00189     c++;
00190 
00191   return c;
00192 }
00193 
00194 int
00195 xlist_is_empty (XList * list)
00196 {
00197   return (list == NULL);
00198 }
00199 
00200 int
00201 xlist_is_singleton (XList * list)
00202 {
00203   if (list == NULL) return 0;
00204   if (list->next == NULL) return 1;
00205   else return 0;
00206 }
00207 
00208 /*
00209  * xlist_free_with (list, free_func)
00210  *
00211  * Step through list 'list', freeing each node using free_func(), and
00212  * also free the list structure itself.
00213  */
00214 XList *
00215 xlist_free_with (XList * list, XFreeFunc free_func)
00216 {
00217   XList * l, * ln;
00218 
00219   for (l = list; l; l = ln) {
00220     ln = l->next;
00221     free_func (l->data);
00222     free (l);
00223   }
00224 
00225   return NULL;
00226 }
00227 
00228 /*
00229  * xlist_free (list)
00230  *
00231  * Free the list structure 'list', but not its nodes.
00232  */
00233 XList *
00234 xlist_free (XList * list)
00235 {
00236   XList * l, * ln;
00237 
00238   for (l = list; l; l = ln) {
00239     ln = l->next;
00240     free (l);
00241   }
00242 
00243   return NULL;
00244 }
00245 

Generated on Tue Dec 20 10:14:28 2005 for vlc-0.8.4a by  doxygen 1.4.2