Moved variable declarations from in-block declarations to be MSVC compiler compliant
[opensync.git] / opensync / opensync_list.c
blobbf13919b8b9c398ac79393f8ba38c3968403f132
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)
29 /*
30 * MT safe
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)
41 OSyncList*
42 osync_list_alloc (void)
44 return _osync_list_alloc0 ();
47 void
48 osync_list_free (OSyncList *list)
50 g_slice_free_chain (OSyncList, list, next);
53 void
54 osync_list_free_1 (OSyncList *list)
56 _osync_list_free1 (list);
59 OSyncList*
60 osync_list_append (OSyncList *list,
61 void * data)
63 OSyncList *new_list;
64 OSyncList *last;
66 new_list = _osync_list_alloc ();
67 new_list->data = data;
68 new_list->next = NULL;
70 if (list)
72 last = osync_list_last (list);
73 /* osync_assert (last != NULL); */
74 last->next = new_list;
75 new_list->prev = last;
77 return list;
79 else
81 new_list->prev = NULL;
82 return new_list;
86 OSyncList*
87 osync_list_prepend (OSyncList *list,
88 void * data)
90 OSyncList *new_list;
92 new_list = _osync_list_alloc ();
93 new_list->data = data;
94 new_list->next = list;
96 if (list)
98 new_list->prev = list->prev;
99 if (list->prev)
100 list->prev->next = new_list;
101 list->prev = new_list;
103 else
104 new_list->prev = NULL;
106 return new_list;
109 OSyncList*
110 osync_list_insert (OSyncList *list,
111 void * data,
112 int position)
114 OSyncList *new_list;
115 OSyncList *tmp_list;
117 if (position < 0)
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);
123 if (!tmp_list)
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;
129 if (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)
135 return new_list;
136 else
137 return list;
140 OSyncList*
141 osync_list_insert_before (OSyncList *list,
142 OSyncList *sibling,
143 void * data)
145 if (!list)
147 list = osync_list_alloc ();
148 list->data = data;
149 g_return_val_if_fail (sibling == NULL, list);
150 return list;
152 else if (sibling)
154 OSyncList *node;
156 node = _osync_list_alloc ();
157 node->data = data;
158 node->prev = sibling->prev;
159 node->next = sibling;
160 sibling->prev = node;
161 if (node->prev)
163 node->prev->next = node;
164 return list;
166 else
168 g_return_val_if_fail (sibling == list, node);
169 return node;
172 else
174 OSyncList *last;
176 last = list;
177 while (last->next)
178 last = last->next;
180 last->next = _osync_list_alloc ();
181 last->next->data = data;
182 last->next->prev = last;
183 last->next->next = NULL;
185 return list;
189 OSyncList *
190 osync_list_concat (OSyncList *list1, OSyncList *list2)
192 OSyncList *tmp_list;
194 if (list2)
196 tmp_list = osync_list_last (list1);
197 if (tmp_list)
198 tmp_list->next = list2;
199 else
200 list1 = list2;
201 list2->prev = tmp_list;
204 return list1;
207 OSyncList*
208 osync_list_remove (OSyncList *list,
209 void * data)
211 OSyncList *tmp;
213 tmp = list;
214 while (tmp)
216 if (tmp->data != data)
217 tmp = tmp->next;
218 else
220 if (tmp->prev)
221 tmp->prev->next = tmp->next;
222 if (tmp->next)
223 tmp->next->prev = tmp->prev;
225 if (list == tmp)
226 list = list->next;
228 _osync_list_free1 (tmp);
230 break;
233 return list;
236 OSyncList*
237 osync_list_remove_all (OSyncList *list,
238 void * data)
240 OSyncList *tmp = list;
242 while (tmp)
244 if (tmp->data != data)
245 tmp = tmp->next;
246 else
248 OSyncList *next = tmp->next;
250 if (tmp->prev)
251 tmp->prev->next = next;
252 else
253 list = next;
254 if (next)
255 next->prev = tmp->prev;
257 _osync_list_free1 (tmp);
258 tmp = next;
261 return list;
264 static inline OSyncList*
265 _osync_list_remove_link (OSyncList *list,
266 OSyncList *link)
268 if (link)
270 if (link->prev)
271 link->prev->next = link->next;
272 if (link->next)
273 link->next->prev = link->prev;
275 if (link == list)
276 list = list->next;
278 link->next = NULL;
279 link->prev = NULL;
282 return list;
285 OSyncList*
286 osync_list_remove_link (OSyncList *list,
287 OSyncList *link)
289 return _osync_list_remove_link (list, link);
292 OSyncList*
293 osync_list_delete_link (OSyncList *list,
294 OSyncList *link)
296 list = _osync_list_remove_link (list, link);
297 _osync_list_free1 (link);
299 return list;
302 OSyncList*
303 osync_list_copy (OSyncList *list)
305 OSyncList *new_list = NULL;
307 if (list)
309 OSyncList *last;
311 new_list = _osync_list_alloc ();
312 new_list->data = list->data;
313 new_list->prev = NULL;
314 last = new_list;
315 list = list->next;
316 while (list)
318 last->next = _osync_list_alloc ();
319 last->next->prev = last;
320 last = last->next;
321 last->data = list->data;
322 list = list->next;
324 last->next = NULL;
327 return new_list;
330 OSyncList*
331 osync_list_reverse (OSyncList *list)
333 OSyncList *last;
335 last = NULL;
336 while (list)
338 last = list;
339 list = last->next;
340 last->next = last->prev;
341 last->prev = list;
344 return last;
347 OSyncList*
348 osync_list_nth (OSyncList *list,
349 unsigned int n)
351 while ((n-- > 0) && list)
352 list = list->next;
354 return list;
357 OSyncList*
358 osync_list_nth_prev (OSyncList *list,
359 unsigned int n)
361 while ((n-- > 0) && list)
362 list = list->prev;
364 return list;
367 void *
368 osync_list_nth_data (OSyncList *list,
369 unsigned int n)
371 while ((n-- > 0) && list)
372 list = list->next;
374 return list ? list->data : NULL;
377 OSyncList*
378 osync_list_find (OSyncList *list,
379 void * data)
381 while (list)
383 if (list->data == data)
384 break;
385 list = list->next;
388 return list;
391 OSyncList*
392 osync_list_find_custom (OSyncList *list,
393 void * data,
394 OSyncCompareFunc func)
396 g_return_val_if_fail (func != NULL, list);
398 while (list)
400 if (! func (list->data, data))
401 return list;
402 list = list->next;
405 return NULL;
410 osync_list_position (OSyncList *list,
411 OSyncList *link)
413 int i;
415 i = 0;
416 while (list)
418 if (list == link)
419 return i;
420 i++;
421 list = list->next;
424 return -1;
428 osync_list_index (OSyncList *list,
429 void * data)
431 int i;
433 i = 0;
434 while (list)
436 if (list->data == data)
437 return i;
438 i++;
439 list = list->next;
442 return -1;
445 OSyncList*
446 osync_list_last (OSyncList *list)
448 if (list)
450 while (list->next)
451 list = list->next;
454 return list;
457 OSyncList*
458 osync_list_first (OSyncList *list)
460 if (list)
462 while (list->prev)
463 list = list->prev;
466 return list;
469 unsigned int
470 osync_list_length (const OSyncList *list)
472 unsigned int length;
474 length = 0;
475 while (list)
477 length++;
478 list = list->next;
481 return length;
484 void
485 osync_list_foreach (OSyncList *list,
486 OSyncFunc func,
487 void * user_data)
489 while (list)
491 OSyncList *next = list->next;
492 (*func) (list->data, user_data);
493 list = next;
497 static OSyncList*
498 osync_list_insert_sorted_real (OSyncList *list,
499 void * data,
500 OSyncFunc func,
501 void * user_data)
503 OSyncList *tmp_list = list;
504 OSyncList *new_list;
505 int cmp;
507 g_return_val_if_fail (func != NULL, list);
509 if (!list)
511 new_list = _osync_list_alloc0 ();
512 new_list->data = data;
513 return new_list;
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;
532 return list;
535 if (tmp_list->prev)
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)
544 return new_list;
545 else
546 return list;
549 OSyncList*
550 osync_list_insert_sorted (OSyncList *list,
551 void * data,
552 OSyncCompareFunc func)
554 return osync_list_insert_sorted_real (list, data, (OSyncFunc) func, NULL);
557 OSyncList*
558 osync_list_insert_sorted_with_data (OSyncList *list,
559 void * data,
560 OSyncCompareDataFunc func,
561 void * user_data)
563 return osync_list_insert_sorted_real (list, data, (OSyncFunc) func, user_data);
566 static OSyncList *
567 osync_list_sort_merge (OSyncList *l1,
568 OSyncList *l2,
569 OSyncFunc compare_func,
570 void * user_data)
572 OSyncList list, *l, *lprev;
573 int cmp;
575 l = &list;
576 lprev = NULL;
578 while (l1 && l2)
580 cmp = ((OSyncCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
582 if (cmp <= 0)
584 l->next = l1;
585 l1 = l1->next;
587 else
589 l->next = l2;
590 l2 = l2->next;
592 l = l->next;
593 l->prev = lprev;
594 lprev = l;
596 l->next = l1 ? l1 : l2;
597 l->next->prev = l;
599 return list.next;
602 static OSyncList*
603 osync_list_sort_real (OSyncList *list,
604 OSyncFunc compare_func,
605 void * user_data)
607 OSyncList *l1, *l2;
609 if (!list)
610 return NULL;
611 if (!list->next)
612 return list;
614 l1 = list;
615 l2 = list->next;
617 while ((l2 = l2->next) != NULL)
619 if ((l2 = l2->next) == NULL)
620 break;
621 l1 = l1->next;
623 l2 = l1->next;
624 l1->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),
628 compare_func,
629 user_data);
632 OSyncList *
633 osync_list_sort (OSyncList *list,
634 OSyncCompareFunc compare_func)
636 return osync_list_sort_real (list, (OSyncFunc) compare_func, NULL);
640 OSyncList *
641 osync_list_sort_with_data (OSyncList *list,
642 OSyncCompareDataFunc compare_func,
643 void * user_data)
645 return osync_list_sort_real (list, (OSyncFunc) compare_func, user_data);