xlist.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:5k
源码类别:

midi

开发平台:

Unix_Linux

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