1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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.
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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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.
21 * Modified by the GLib Team and others 1997-2000. 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/.
26 * Modified for OpenSync by Armin Bauer (armin.bauer@desscon.com)
33 #include <glib/gmem.h>
34 #include "opensync_list.h"
35 #include "opensync_internals.h"
37 #define _osync_list_alloc() g_slice_new (OSyncList)
38 #define _osync_list_alloc0() g_slice_new0 (OSyncList)
39 #define _osync_list_free1(list) g_slice_free (OSyncList, list)
42 osync_list_alloc (void)
44 return _osync_list_alloc0 ();
48 osync_list_free (OSyncList
*list
)
50 g_slice_free_chain (OSyncList
, list
, next
);
54 osync_list_free_1 (OSyncList
*list
)
56 _osync_list_free1 (list
);
60 osync_list_append (OSyncList
*list
,
66 new_list
= _osync_list_alloc ();
67 new_list
->data
= data
;
68 new_list
->next
= NULL
;
72 last
= osync_list_last (list
);
73 /* osync_assert (last != NULL); */
74 last
->next
= new_list
;
75 new_list
->prev
= last
;
81 new_list
->prev
= NULL
;
87 osync_list_prepend (OSyncList
*list
,
92 new_list
= _osync_list_alloc ();
93 new_list
->data
= data
;
94 new_list
->next
= list
;
98 new_list
->prev
= list
->prev
;
100 list
->prev
->next
= new_list
;
101 list
->prev
= new_list
;
104 new_list
->prev
= NULL
;
110 osync_list_insert (OSyncList
*list
,
118 return osync_list_append (list
, data
);
119 else if (position
== 0)
120 return osync_list_prepend (list
, data
);
122 tmp_list
= osync_list_nth (list
, position
);
124 return osync_list_append (list
, data
);
126 new_list
= _osync_list_alloc ();
127 new_list
->data
= data
;
128 new_list
->prev
= tmp_list
->prev
;
130 tmp_list
->prev
->next
= new_list
;
131 new_list
->next
= tmp_list
;
132 tmp_list
->prev
= new_list
;
134 if (tmp_list
== list
)
141 osync_list_insert_before (OSyncList
*list
,
147 list
= osync_list_alloc ();
149 g_return_val_if_fail (sibling
== NULL
, list
);
156 node
= _osync_list_alloc ();
158 node
->prev
= sibling
->prev
;
159 node
->next
= sibling
;
160 sibling
->prev
= node
;
163 node
->prev
->next
= node
;
168 g_return_val_if_fail (sibling
== list
, node
);
180 last
->next
= _osync_list_alloc ();
181 last
->next
->data
= data
;
182 last
->next
->prev
= last
;
183 last
->next
->next
= NULL
;
190 osync_list_concat (OSyncList
*list1
, OSyncList
*list2
)
196 tmp_list
= osync_list_last (list1
);
198 tmp_list
->next
= list2
;
201 list2
->prev
= tmp_list
;
208 osync_list_remove (OSyncList
*list
,
216 if (tmp
->data
!= data
)
221 tmp
->prev
->next
= tmp
->next
;
223 tmp
->next
->prev
= tmp
->prev
;
228 _osync_list_free1 (tmp
);
237 osync_list_remove_all (OSyncList
*list
,
240 OSyncList
*tmp
= list
;
244 if (tmp
->data
!= data
)
248 OSyncList
*next
= tmp
->next
;
251 tmp
->prev
->next
= next
;
255 next
->prev
= tmp
->prev
;
257 _osync_list_free1 (tmp
);
264 static inline OSyncList
*
265 _osync_list_remove_link (OSyncList
*list
,
271 link
->prev
->next
= link
->next
;
273 link
->next
->prev
= link
->prev
;
286 osync_list_remove_link (OSyncList
*list
,
289 return _osync_list_remove_link (list
, link
);
293 osync_list_delete_link (OSyncList
*list
,
296 list
= _osync_list_remove_link (list
, link
);
297 _osync_list_free1 (link
);
303 osync_list_copy (OSyncList
*list
)
305 OSyncList
*new_list
= NULL
;
311 new_list
= _osync_list_alloc ();
312 new_list
->data
= list
->data
;
313 new_list
->prev
= NULL
;
318 last
->next
= _osync_list_alloc ();
319 last
->next
->prev
= last
;
321 last
->data
= list
->data
;
331 osync_list_reverse (OSyncList
*list
)
340 last
->next
= last
->prev
;
348 osync_list_nth (OSyncList
*list
,
351 while ((n
-- > 0) && list
)
358 osync_list_nth_prev (OSyncList
*list
,
361 while ((n
-- > 0) && list
)
368 osync_list_nth_data (OSyncList
*list
,
371 while ((n
-- > 0) && list
)
374 return list
? list
->data
: NULL
;
378 osync_list_find (OSyncList
*list
,
383 if (list
->data
== data
)
392 osync_list_find_custom (OSyncList
*list
,
394 OSyncCompareFunc func
)
396 g_return_val_if_fail (func
!= NULL
, list
);
400 if (! func (list
->data
, data
))
410 osync_list_position (OSyncList
*list
,
428 osync_list_index (OSyncList
*list
,
436 if (list
->data
== data
)
446 osync_list_last (OSyncList
*list
)
458 osync_list_first (OSyncList
*list
)
470 osync_list_length (const OSyncList
*list
)
485 osync_list_foreach (OSyncList
*list
,
491 OSyncList
*next
= list
->next
;
492 (*func
) (list
->data
, user_data
);
498 osync_list_insert_sorted_real (OSyncList
*list
,
503 OSyncList
*tmp_list
= list
;
507 g_return_val_if_fail (func
!= NULL
, list
);
511 new_list
= _osync_list_alloc0 ();
512 new_list
->data
= data
;
516 cmp
= ((OSyncCompareDataFunc
) func
) (data
, tmp_list
->data
, user_data
);
518 while ((tmp_list
->next
) && (cmp
> 0))
520 tmp_list
= tmp_list
->next
;
522 cmp
= ((OSyncCompareDataFunc
) func
) (data
, tmp_list
->data
, user_data
);
525 new_list
= _osync_list_alloc0 ();
526 new_list
->data
= data
;
528 if ((!tmp_list
->next
) && (cmp
> 0))
530 tmp_list
->next
= new_list
;
531 new_list
->prev
= tmp_list
;
537 tmp_list
->prev
->next
= new_list
;
538 new_list
->prev
= tmp_list
->prev
;
540 new_list
->next
= tmp_list
;
541 tmp_list
->prev
= new_list
;
543 if (tmp_list
== list
)
550 osync_list_insert_sorted (OSyncList
*list
,
552 OSyncCompareFunc func
)
554 return osync_list_insert_sorted_real (list
, data
, (OSyncFunc
) func
, NULL
);
558 osync_list_insert_sorted_with_data (OSyncList
*list
,
560 OSyncCompareDataFunc func
,
563 return osync_list_insert_sorted_real (list
, data
, (OSyncFunc
) func
, user_data
);
567 osync_list_sort_merge (OSyncList
*l1
,
569 OSyncFunc compare_func
,
572 OSyncList list
, *l
, *lprev
;
580 cmp
= ((OSyncCompareDataFunc
) compare_func
) (l1
->data
, l2
->data
, user_data
);
596 l
->next
= l1
? l1
: l2
;
603 osync_list_sort_real (OSyncList
*list
,
604 OSyncFunc compare_func
,
617 while ((l2
= l2
->next
) != NULL
)
619 if ((l2
= l2
->next
) == NULL
)
626 return osync_list_sort_merge (osync_list_sort_real (list
, compare_func
, user_data
),
627 osync_list_sort_real (l2
, compare_func
, user_data
),
633 osync_list_sort (OSyncList
*list
,
634 OSyncCompareFunc compare_func
)
636 return osync_list_sort_real (list
, (OSyncFunc
) compare_func
, NULL
);
641 osync_list_sort_with_data (OSyncList
*list
,
642 OSyncCompareDataFunc compare_func
,
645 return osync_list_sort_real (list
, (OSyncFunc
) compare_func
, user_data
);