1/* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GLib Team and others 1997-1999.  See the AUTHORS
22 * file for a list of people on the GLib Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27
28
29#include "fluid_list.h"
30
31
32fluid_list_t*
33new_fluid_list(void)
34{
35  fluid_list_t* list;
36  list = (fluid_list_t*) FLUID_MALLOC(sizeof(fluid_list_t));
37  list->data = NULL;
38  list->next = NULL;
39  return list;
40}
41
42void
43delete_fluid_list(fluid_list_t *list)
44{
45  fluid_list_t *next;
46  while (list) {
47    next = list->next;
48    FLUID_FREE(list);
49    list = next;
50  }
51}
52
53void
54delete1_fluid_list(fluid_list_t *list)
55{
56  if (list) {
57    FLUID_FREE(list);
58  }
59}
60
61fluid_list_t*
62fluid_list_append(fluid_list_t *list, void*  data)
63{
64  fluid_list_t *new_list;
65  fluid_list_t *last;
66
67  new_list = new_fluid_list();
68  new_list->data = data;
69
70  if (list)
71    {
72      last = fluid_list_last(list);
73      /* g_assert (last != NULL); */
74      last->next = new_list;
75
76      return list;
77    }
78  else
79      return new_list;
80}
81
82fluid_list_t*
83fluid_list_prepend(fluid_list_t *list, void* data)
84{
85  fluid_list_t *new_list;
86
87  new_list = new_fluid_list();
88  new_list->data = data;
89  new_list->next = list;
90
91  return new_list;
92}
93
94fluid_list_t*
95fluid_list_nth(fluid_list_t *list, int n)
96{
97  while ((n-- > 0) && list) {
98    list = list->next;
99  }
100
101  return list;
102}
103
104fluid_list_t*
105fluid_list_remove(fluid_list_t *list, void* data)
106{
107  fluid_list_t *tmp;
108  fluid_list_t *prev;
109
110  prev = NULL;
111  tmp = list;
112
113  while (tmp) {
114    if (tmp->data == data) {
115      if (prev) {
116	prev->next = tmp->next;
117      }
118      if (list == tmp) {
119	list = list->next;
120      }
121      tmp->next = NULL;
122      delete_fluid_list(tmp);
123
124      break;
125    }
126
127    prev = tmp;
128    tmp = tmp->next;
129  }
130
131  return list;
132}
133
134fluid_list_t*
135fluid_list_remove_link(fluid_list_t *list, fluid_list_t *link)
136{
137  fluid_list_t *tmp;
138  fluid_list_t *prev;
139
140  prev = NULL;
141  tmp = list;
142
143  while (tmp) {
144    if (tmp == link) {
145      if (prev) {
146	prev->next = tmp->next;
147      }
148      if (list == tmp) {
149	list = list->next;
150      }
151      tmp->next = NULL;
152      break;
153    }
154
155    prev = tmp;
156    tmp = tmp->next;
157  }
158
159  return list;
160}
161
162static fluid_list_t*
163fluid_list_sort_merge(fluid_list_t *l1, fluid_list_t *l2, fluid_compare_func_t compare_func)
164{
165  fluid_list_t list, *l;
166
167  l = &list;
168
169  while (l1 && l2) {
170    if (compare_func(l1->data,l2->data) < 0) {
171      l = l->next = l1;
172      l1 = l1->next;
173    } else {
174      l = l->next = l2;
175      l2 = l2->next;
176    }
177  }
178  l->next= l1 ? l1 : l2;
179
180  return list.next;
181}
182
183fluid_list_t*
184fluid_list_sort(fluid_list_t *list, fluid_compare_func_t compare_func)
185{
186  fluid_list_t *l1, *l2;
187
188  if (!list) {
189    return NULL;
190  }
191  if (!list->next) {
192    return list;
193  }
194
195  l1 = list;
196  l2 = list->next;
197
198  while ((l2 = l2->next) != NULL) {
199    if ((l2 = l2->next) == NULL)
200      break;
201    l1=l1->next;
202  }
203  l2 = l1->next;
204  l1->next = NULL;
205
206  return fluid_list_sort_merge(fluid_list_sort(list, compare_func),
207			      fluid_list_sort(l2, compare_func),
208			      compare_func);
209}
210
211
212fluid_list_t*
213fluid_list_last(fluid_list_t *list)
214{
215  if (list) {
216    while (list->next)
217      list = list->next;
218  }
219
220  return list;
221}
222
223int
224fluid_list_size(fluid_list_t *list)
225{
226  int n = 0;
227  while (list) {
228    n++;
229    list = list->next;
230  }
231  return n;
232}
233
234fluid_list_t* fluid_list_insert_at(fluid_list_t *list, int n, void* data)
235{
236  fluid_list_t *new_list;
237  fluid_list_t *cur;
238  fluid_list_t *prev = NULL;
239
240  new_list = new_fluid_list();
241  new_list->data = data;
242
243  cur = list;
244  while ((n-- > 0) && cur) {
245    prev = cur;
246    cur = cur->next;
247  }
248
249  new_list->next = cur;
250
251  if (prev) {
252    prev->next = new_list;
253    return list;
254  } else {
255    return new_list;
256  }
257}
258