xlist.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:5k
源码类别:

多媒体

开发平台:

MultiPlatform

  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 VideoLAN
  7.  *
  8.  * $Id: xlist.c 7397 2004-04-20 17:27:30Z sam $
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  26.  *****************************************************************************/
  27. #include <stdlib.h>
  28. #include "xlist.h"
  29. static XList *
  30. xlist_node_new (void * data)
  31. {
  32.   XList * l;
  33.   l = (XList *) malloc (sizeof (XList));
  34.   l->prev = l->next = NULL;
  35.   l->data = data;
  36.   return l;
  37. }
  38. XList *
  39. xlist_new (void)
  40. {
  41.   return NULL;
  42. }
  43. XList *
  44. xlist_clone (XList * list)
  45. {
  46.   XList * l, * new_list;
  47.   if (list == NULL) return NULL;
  48.   new_list = xlist_new ();
  49.   for (l = list; l; l = l->next) {
  50.     new_list = xlist_append (new_list, l->data);
  51.   }
  52.   return new_list;
  53. }
  54. XList *
  55. xlist_clone_with (XList * list, XCloneFunc clone)
  56. {
  57.   XList * l, * new_list;
  58.   void * new_data;
  59.   if (list == NULL) return NULL;
  60.   if (clone == NULL) return xlist_clone (list);
  61.   new_list = xlist_new ();
  62.   for (l = list; l; l = l->next) {
  63.     new_data = clone (l->data);
  64.     new_list = xlist_append (new_list, new_data);
  65.   }
  66.   return new_list;
  67. }
  68. XList *
  69. xlist_tail (XList * list)
  70. {
  71.   XList * l;
  72.   for (l = list; l; l = l->next)
  73.     if (l->next == NULL) return l;
  74.   return NULL;
  75. }
  76. XList *
  77. xlist_prepend (XList * list, void * data)
  78. {
  79.   XList * l = xlist_node_new (data);
  80.   if (list == NULL) return l;
  81.   l->next = list;
  82.   list->prev = l;
  83.   return l;
  84. }
  85. XList *
  86. xlist_append (XList * list, void * data)
  87. {
  88.   XList * l = xlist_node_new (data);
  89.   XList * last;
  90.   if (list == NULL) return l;
  91.   last = xlist_tail (list);
  92.   if (last) last->next = l;
  93.   l->prev = last; 
  94.   return list;
  95. }
  96. XList *
  97. xlist_add_before (XList * list, void * data, XList * node)
  98. {
  99.   XList * l, * p;
  100.   if (list == NULL) return xlist_node_new (data);
  101.   if (node == NULL) return xlist_append (list, data);
  102.   if (node == list) return xlist_prepend (list, data);
  103.   l = xlist_node_new (data);
  104.   p = node->prev;
  105.   l->prev = p;
  106.   l->next = node;
  107.   if (p) p->next = l;
  108.   node->prev = l;
  109.   
  110.   return list;
  111. }
  112. XList *
  113. xlist_add_after (XList * list, void * data, XList * node)
  114. {
  115.   XList * l, * n;
  116.   if (node == NULL) return xlist_prepend (list, data);
  117.   l = xlist_node_new (data);
  118.   n = node->next;
  119.   l->prev = node;
  120.   l->next = n;
  121.   if (n) n->prev = l;
  122.   node->next = l;
  123.   return list;
  124. }
  125. XList *
  126. xlist_find (XList * list, void * data)
  127. {
  128.   XList * l;
  129.   for (l = list; l; l = l->next)
  130.     if (l->data == data) return l;
  131.   return NULL;
  132. }
  133. XList *
  134. xlist_remove (XList * list, XList * node)
  135. {
  136.   if (node == NULL) return list;
  137.   if (node->prev) node->prev->next = node->next;
  138.   if (node->next) node->next->prev = node->prev;
  139.   if (node == list) return list->next;
  140.   else return list;
  141. }
  142. int
  143. xlist_length (XList * list)
  144. {
  145.   XList * l;
  146.   int c = 0;
  147.   for (l = list; l; l = l->next)
  148.     c++;
  149.   return c;
  150. }
  151. int
  152. xlist_is_empty (XList * list)
  153. {
  154.   return (list == NULL);
  155. }
  156. int
  157. xlist_is_singleton (XList * list)
  158. {
  159.   if (list == NULL) return 0;
  160.   if (list->next == NULL) return 1;
  161.   else return 0;
  162. }
  163. /*
  164.  * xlist_free_with (list, free_func)
  165.  *
  166.  * Step through list 'list', freeing each node using free_func(), and
  167.  * also free the list structure itself.
  168.  */
  169. XList *
  170. xlist_free_with (XList * list, XFreeFunc free_func)
  171. {
  172.   XList * l, * ln;
  173.   for (l = list; l; l = ln) {
  174.     ln = l->next;
  175.     free_func (l->data);
  176.     free (l);
  177.   }
  178.   return NULL;
  179. }
  180. /*
  181.  * xlist_free (list)
  182.  *
  183.  * Free the list structure 'list', but not its nodes.
  184.  */
  185. XList *
  186. xlist_free (XList * list)
  187. {
  188.   XList * l, * ln;
  189.   for (l = list; l; l = ln) {
  190.     ln = l->next;
  191.     free (l);
  192.   }
  193.   return NULL;
  194. }