xlist.c

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2005 Commonwealth Scientific and Industrial Research
00003 //                   Organisation (CSIRO) Australia
00004 //
00005 //Redistribution and use in source and binary forms, with or without
00006 //modification, are permitted provided that the following conditions
00007 //are met:
00008 //
00009 //- Redistributions of source code must retain the above copyright
00010 //  notice, this list of conditions and the following disclaimer.
00011 //
00012 //- Redistributions in binary form must reproduce the above copyright
00013 //  notice, this list of conditions and the following disclaimer in the
00014 //  documentation and/or other materials provided with the distribution.
00015 //
00016 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00017 //  may be used to endorse or promote products derived from this software 
00018 //  without specific prior written permission.
00019 //
00020 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00024 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 //===========================================================================
00032 
00033 #include <stdlib.h>
00034 
00035 #include "stdafx.h"
00036 #include "xlist.h"
00037 
00038 static XList *
00039 xlist_node_new (void * data)
00040 {
00041   XList * l;
00042 
00043   l = (XList *) malloc (sizeof (XList));
00044   l->prev = l->next = NULL;
00045   l->data = data;
00046 
00047   return l;
00048 }
00049 
00050 XList *
00051 xlist_new (void)
00052 {
00053   return NULL;
00054 }
00055 
00056 XList *
00057 xlist_clone (XList * list)
00058 {
00059   XList * l, * new_list;
00060 
00061   if (list == NULL) return NULL;
00062   new_list = xlist_new ();
00063 
00064   for (l = list; l; l = l->next) {
00065     new_list = xlist_append (new_list, l->data);
00066   }
00067 
00068   return new_list;
00069 }
00070 
00071 XList *
00072 xlist_clone_with (XList * list, XCloneFunc clone)
00073 {
00074   XList * l, * new_list;
00075   void * new_data;
00076 
00077   if (list == NULL) return NULL;
00078   if (clone == NULL) return xlist_clone (list);
00079 
00080   new_list = xlist_new ();
00081 
00082   for (l = list; l; l = l->next) {
00083     new_data = clone (l->data);
00084     new_list = xlist_append (new_list, new_data);
00085   }
00086 
00087   return new_list;
00088 }
00089 
00090 
00091 XList *
00092 xlist_tail (XList * list)
00093 {
00094   XList * l;
00095   for (l = list; l; l = l->next)
00096     if (l->next == NULL) return l;
00097   return NULL;
00098 }
00099 
00100 XList *
00101 xlist_prepend (XList * list, void * data)
00102 {
00103   XList * l = xlist_node_new (data);
00104 
00105   if (list == NULL) return l;
00106 
00107   l->next = list;
00108   list->prev = l;
00109 
00110   return l;
00111 }
00112 
00113 XList *
00114 xlist_append (XList * list, void * data)
00115 {
00116   XList * l = xlist_node_new (data);
00117   XList * last;
00118 
00119   if (list == NULL) return l;
00120 
00121   last = xlist_tail (list);
00122   if (last) last->next = l;
00123   l->prev = last; 
00124   return list;
00125 }
00126 
00127 XList *
00128 xlist_add_before (XList * list, void * data, XList * node)
00129 {
00130   XList * l, * p;
00131 
00132   if (list == NULL) return xlist_node_new (data);
00133   if (node == NULL) return xlist_append (list, data);
00134   if (node == list) return xlist_prepend (list, data);
00135 
00136   l = xlist_node_new (data);
00137   p = node->prev;
00138 
00139   l->prev = p;
00140   l->next = node;
00141   if (p) p->next = l;
00142   node->prev = l;
00143   
00144   return list;
00145 }
00146 
00147 XList *
00148 xlist_add_after (XList * list, void * data, XList * node)
00149 {
00150   XList * l, * n;
00151 
00152   if (node == NULL) return xlist_prepend (list, data);
00153 
00154   l = xlist_node_new (data);
00155   n = node->next;
00156 
00157   l->prev = node;
00158   l->next = n;
00159   if (n) n->prev = l;
00160   node->next = l;
00161 
00162   return list;
00163 }
00164 
00165 XList *
00166 xlist_find (XList * list, void * data)
00167 {
00168   XList * l;
00169 
00170   for (l = list; l; l = l->next)
00171     if (l->data == data) return l;
00172 
00173   return NULL;
00174 }
00175 
00176 XList *
00177 xlist_remove (XList * list, XList * node)
00178 {
00179   if (node == NULL) return list;
00180 
00181   if (node->prev) node->prev->next = node->next;
00182   if (node->next) node->next->prev = node->prev;
00183 
00184   if (node == list) return list->next;
00185   else return list;
00186 }
00187 
00188 int
00189 xlist_length (XList * list)
00190 {
00191   XList * l;
00192   int c = 0;
00193 
00194   for (l = list; l; l = l->next)
00195     c++;
00196 
00197   return c;
00198 }
00199 
00200 int
00201 xlist_is_empty (XList * list)
00202 {
00203   return (list == NULL);
00204 }
00205 
00206 int
00207 xlist_is_singleton (XList * list)
00208 {
00209   if (list == NULL) return 0;
00210   if (list->next == NULL) return 1;
00211   else return 0;
00212 }
00213 
00214 /*
00215  * xlist_free_with (list, free_func)
00216  *
00217  * Step through list 'list', freeing each node using free_func(), and
00218  * also free the list structure itself.
00219  */
00220 XList *
00221 xlist_free_with (XList * list, XFreeFunc free_func)
00222 {
00223   XList * l, * ln;
00224 
00225   for (l = list; l; l = ln) {
00226     ln = l->next;
00227     free_func (l->data);
00228     free (l);
00229   }
00230 
00231   return NULL;
00232 }
00233 
00234 /*
00235  * xlist_free (list)
00236  *
00237  * Free the list structure 'list', but not its nodes.
00238  */
00239 XList *
00240 xlist_free (XList * list)
00241 {
00242   XList * l, * ln;
00243 
00244   for (l = list; l; l = ln) {
00245     ln = l->next;
00246     free (l);
00247   }
00248 
00249   return NULL;
00250 }
00251 

Generated on Tue Feb 15 14:54:13 2005 for oggdsf by  doxygen 1.3.9