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 Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GLib Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GLib at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25 /*
26 * MT safe
27 */
28
29 #include "config.h"
30
31 #include "glist.h"
32 #include "gslice.h"
33 #include "gmessages.h"
34
35 #include "gtestutils.h"
36
37 /**
38 * SECTION:linked_lists_double
39 * @title: Doubly-Linked Lists
40 * @short_description: linked lists that can be iterated over in both directions
41 *
42 * The #GList structure and its associated functions provide a standard
43 * doubly-linked list data structure.
44 *
45 * Each element in the list contains a piece of data, together with
46 * pointers which link to the previous and next elements in the list.
47 * Using these pointers it is possible to move through the list in both
48 * directions (unlike the singly-linked [GSList][glib-Singly-Linked-Lists],
49 * which only allows movement through the list in the forward direction).
50 *
51 * The double linked list does not keep track of the number of items
52 * and does not keep track of both the start and end of the list. If
53 * you want fast access to both the start and the end of the list,
54 * and/or the number of items in the list, use a
55 * [GQueue][glib-Double-ended-Queues] instead.
56 *
57 * The data contained in each element can be either integer values, by
58 * using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
59 * or simply pointers to any type of data.
60 *
61 * List elements are allocated from the [slice allocator][glib-Memory-Slices],
62 * which is more efficient than allocating elements individually.
63 *
64 * Note that most of the #GList functions expect to be passed a pointer
65 * to the first element in the list. The functions which insert
66 * elements return the new start of the list, which may have changed.
67 *
68 * There is no function to create a #GList. %NULL is considered to be
69 * a valid, empty list so you simply set a #GList* to %NULL to initialize
70 * it.
71 *
72 * To add elements, use g_list_append(), g_list_prepend(),
73 * g_list_insert() and g_list_insert_sorted().
74 *
75 * To visit all elements in the list, use a loop over the list:
76 * |[<!-- language="C" -->
77 * GList *l;
78 * for (l = list; l != NULL; l = l->next)
79 * {
80 * // do something with l->data
81 * }
82 * ]|
83 *
84 * To call a function for each element in the list, use g_list_foreach().
85 *
86 * To loop over the list and modify it (e.g. remove a certain element)
87 * a while loop is more appropriate, for example:
88 * |[<!-- language="C" -->
89 * GList *l = list;
90 * while (l != NULL)
91 * {
92 * GList *next = l->next;
93 * if (should_be_removed (l))
94 * {
95 * // possibly free l->data
96 * list = g_list_delete_link (list, l);
97 * }
98 * l = next;
99 * }
100 * ]|
101 *
102 * To remove elements, use g_list_remove().
103 *
104 * To navigate in a list, use g_list_first(), g_list_last(),
105 * g_list_next(), g_list_previous().
106 *
107 * To find elements in the list use g_list_nth(), g_list_nth_data(),
108 * g_list_find() and g_list_find_custom().
109 *
110 * To find the index of an element use g_list_position() and
111 * g_list_index().
112 *
113 * To free the entire list, use g_list_free() or g_list_free_full().
114 */
115
116 /**
117 * GList:
118 * @data: holds the element's data, which can be a pointer to any kind
119 * of data, or any integer value using the
120 * [Type Conversion Macros][glib-Type-Conversion-Macros]
121 * @next: contains the link to the next element in the list
122 * @prev: contains the link to the previous element in the list
123 *
124 * The #GList struct is used for each element in a doubly-linked list.
125 **/
126
127 /**
128 * g_list_previous:
129 * @list: an element in a #GList
130 *
131 * A convenience macro to get the previous element in a #GList.
132 * Note that it is considered perfectly acceptable to access
133 * @list->prev directly.
134 *
135 * Returns: the previous element, or %NULL if there are no previous
136 * elements
137 **/
138
139 /**
140 * g_list_next:
141 * @list: an element in a #GList
142 *
143 * A convenience macro to get the next element in a #GList.
144 * Note that it is considered perfectly acceptable to access
145 * @list->next directly.
146 *
147 * Returns: the next element, or %NULL if there are no more elements
148 **/
149
150 #define _g_list_alloc() g_slice_new (GList)
151 #define _g_list_alloc0() g_slice_new0 (GList)
152 #define _g_list_free1(list) g_slice_free (GList, list)
153
154 /**
155 * g_list_alloc:
156 *
157 * Allocates space for one #GList element. It is called by
158 * g_list_append(), g_list_prepend(), g_list_insert() and
159 * g_list_insert_sorted() and so is rarely used on its own.
160 *
161 * Returns: a pointer to the newly-allocated #GList element
162 **/
163 GList *
g_list_alloc(void)164 g_list_alloc (void)
165 {
166 return _g_list_alloc0 ();
167 }
168
169 /**
170 * g_list_free:
171 * @list: a #GList
172 *
173 * Frees all of the memory used by a #GList.
174 * The freed elements are returned to the slice allocator.
175 *
176 * If list elements contain dynamically-allocated memory, you should
177 * either use g_list_free_full() or free them manually first.
178 */
179 void
g_list_free(GList * list)180 g_list_free (GList *list)
181 {
182 g_slice_free_chain (GList, list, next);
183 }
184
185 /**
186 * g_list_free_1:
187 * @list: a #GList element
188 *
189 * Frees one #GList element, but does not update links from the next and
190 * previous elements in the list, so you should not call this function on an
191 * element that is currently part of a list.
192 *
193 * It is usually used after g_list_remove_link().
194 */
195 /**
196 * g_list_free1:
197 *
198 * Another name for g_list_free_1().
199 **/
200 void
g_list_free_1(GList * list)201 g_list_free_1 (GList *list)
202 {
203 _g_list_free1 (list);
204 }
205
206 /**
207 * g_list_free_full:
208 * @list: a pointer to a #GList
209 * @free_func: the function to be called to free each element's data
210 *
211 * Convenience method, which frees all the memory used by a #GList,
212 * and calls @free_func on every element's data.
213 *
214 * @free_func must not modify the list (eg, by removing the freed
215 * element from it).
216 *
217 * Since: 2.28
218 */
219 void
g_list_free_full(GList * list,GDestroyNotify free_func)220 g_list_free_full (GList *list,
221 GDestroyNotify free_func)
222 {
223 g_list_foreach (list, (GFunc) free_func, NULL);
224 g_list_free (list);
225 }
226
227 /**
228 * g_list_append:
229 * @list: a pointer to a #GList
230 * @data: the data for the new element
231 *
232 * Adds a new element on to the end of the list.
233 *
234 * Note that the return value is the new start of the list,
235 * if @list was empty; make sure you store the new value.
236 *
237 * g_list_append() has to traverse the entire list to find the end,
238 * which is inefficient when adding multiple elements. A common idiom
239 * to avoid the inefficiency is to use g_list_prepend() and reverse
240 * the list with g_list_reverse() when all elements have been added.
241 *
242 * |[<!-- language="C" -->
243 * // Notice that these are initialized to the empty list.
244 * GList *string_list = NULL, *number_list = NULL;
245 *
246 * // This is a list of strings.
247 * string_list = g_list_append (string_list, "first");
248 * string_list = g_list_append (string_list, "second");
249 *
250 * // This is a list of integers.
251 * number_list = g_list_append (number_list, GINT_TO_POINTER (27));
252 * number_list = g_list_append (number_list, GINT_TO_POINTER (14));
253 * ]|
254 *
255 * Returns: either @list or the new start of the #GList if @list was %NULL
256 */
257 GList *
g_list_append(GList * list,gpointer data)258 g_list_append (GList *list,
259 gpointer data)
260 {
261 GList *new_list;
262 GList *last;
263
264 new_list = _g_list_alloc ();
265 new_list->data = data;
266 new_list->next = NULL;
267
268 if (list)
269 {
270 last = g_list_last (list);
271 /* g_assert (last != NULL); */
272 last->next = new_list;
273 new_list->prev = last;
274
275 return list;
276 }
277 else
278 {
279 new_list->prev = NULL;
280 return new_list;
281 }
282 }
283
284 /**
285 * g_list_prepend:
286 * @list: a pointer to a #GList, this must point to the top of the list
287 * @data: the data for the new element
288 *
289 * Prepends a new element on to the start of the list.
290 *
291 * Note that the return value is the new start of the list,
292 * which will have changed, so make sure you store the new value.
293 *
294 * |[<!-- language="C" -->
295 * // Notice that it is initialized to the empty list.
296 * GList *list = NULL;
297 *
298 * list = g_list_prepend (list, "last");
299 * list = g_list_prepend (list, "first");
300 * ]|
301 *
302 * Do not use this function to prepend a new element to a different
303 * element than the start of the list. Use g_list_insert_before() instead.
304 *
305 * Returns: a pointer to the newly prepended element, which is the new
306 * start of the #GList
307 */
308 GList *
g_list_prepend(GList * list,gpointer data)309 g_list_prepend (GList *list,
310 gpointer data)
311 {
312 GList *new_list;
313
314 new_list = _g_list_alloc ();
315 new_list->data = data;
316 new_list->next = list;
317
318 if (list)
319 {
320 new_list->prev = list->prev;
321 if (list->prev)
322 list->prev->next = new_list;
323 list->prev = new_list;
324 }
325 else
326 new_list->prev = NULL;
327
328 return new_list;
329 }
330
331 /**
332 * g_list_insert:
333 * @list: a pointer to a #GList, this must point to the top of the list
334 * @data: the data for the new element
335 * @position: the position to insert the element. If this is
336 * negative, or is larger than the number of elements in the
337 * list, the new element is added on to the end of the list.
338 *
339 * Inserts a new element into the list at the given position.
340 *
341 * Returns: the (possibly changed) start of the #GList
342 */
343 GList *
g_list_insert(GList * list,gpointer data,gint position)344 g_list_insert (GList *list,
345 gpointer data,
346 gint position)
347 {
348 GList *new_list;
349 GList *tmp_list;
350
351 if (position < 0)
352 return g_list_append (list, data);
353 else if (position == 0)
354 return g_list_prepend (list, data);
355
356 tmp_list = g_list_nth (list, position);
357 if (!tmp_list)
358 return g_list_append (list, data);
359
360 new_list = _g_list_alloc ();
361 new_list->data = data;
362 new_list->prev = tmp_list->prev;
363 tmp_list->prev->next = new_list;
364 new_list->next = tmp_list;
365 tmp_list->prev = new_list;
366
367 return list;
368 }
369
370 /**
371 * g_list_insert_before_link:
372 * @list: a pointer to a #GList, this must point to the top of the list
373 * @sibling: (nullable): the list element before which the new element
374 * is inserted or %NULL to insert at the end of the list
375 * @link_: the list element to be added, which must not be part of
376 * any other list
377 *
378 * Inserts @link_ into the list before the given position.
379 *
380 * Returns: the (possibly changed) start of the #GList
381 *
382 * Since: 2.62
383 */
384 GList *
g_list_insert_before_link(GList * list,GList * sibling,GList * link_)385 g_list_insert_before_link (GList *list,
386 GList *sibling,
387 GList *link_)
388 {
389 g_return_val_if_fail (link_ != NULL, list);
390 g_return_val_if_fail (link_->prev == NULL, list);
391 g_return_val_if_fail (link_->next == NULL, list);
392
393 if (list == NULL)
394 {
395 g_return_val_if_fail (sibling == NULL, list);
396 return link_;
397 }
398 else if (sibling != NULL)
399 {
400 link_->prev = sibling->prev;
401 link_->next = sibling;
402 sibling->prev = link_;
403 if (link_->prev != NULL)
404 {
405 link_->prev->next = link_;
406 return list;
407 }
408 else
409 {
410 g_return_val_if_fail (sibling == list, link_);
411 return link_;
412 }
413 }
414 else
415 {
416 GList *last;
417
418 for (last = list; last->next != NULL; last = last->next) {}
419
420 last->next = link_;
421 last->next->prev = last;
422 last->next->next = NULL;
423
424 return list;
425 }
426 }
427
428 /**
429 * g_list_insert_before:
430 * @list: a pointer to a #GList, this must point to the top of the list
431 * @sibling: the list element before which the new element
432 * is inserted or %NULL to insert at the end of the list
433 * @data: the data for the new element
434 *
435 * Inserts a new element into the list before the given position.
436 *
437 * Returns: the (possibly changed) start of the #GList
438 */
439 GList *
g_list_insert_before(GList * list,GList * sibling,gpointer data)440 g_list_insert_before (GList *list,
441 GList *sibling,
442 gpointer data)
443 {
444 if (list == NULL)
445 {
446 list = g_list_alloc ();
447 list->data = data;
448 g_return_val_if_fail (sibling == NULL, list);
449 return list;
450 }
451 else if (sibling != NULL)
452 {
453 GList *node;
454
455 node = _g_list_alloc ();
456 node->data = data;
457 node->prev = sibling->prev;
458 node->next = sibling;
459 sibling->prev = node;
460 if (node->prev != NULL)
461 {
462 node->prev->next = node;
463 return list;
464 }
465 else
466 {
467 g_return_val_if_fail (sibling == list, node);
468 return node;
469 }
470 }
471 else
472 {
473 GList *last;
474
475 for (last = list; last->next != NULL; last = last->next) {}
476
477 last->next = _g_list_alloc ();
478 last->next->data = data;
479 last->next->prev = last;
480 last->next->next = NULL;
481
482 return list;
483 }
484 }
485
486 /**
487 * g_list_concat:
488 * @list1: a #GList, this must point to the top of the list
489 * @list2: the #GList to add to the end of the first #GList,
490 * this must point to the top of the list
491 *
492 * Adds the second #GList onto the end of the first #GList.
493 * Note that the elements of the second #GList are not copied.
494 * They are used directly.
495 *
496 * This function is for example used to move an element in the list.
497 * The following example moves an element to the top of the list:
498 * |[<!-- language="C" -->
499 * list = g_list_remove_link (list, llink);
500 * list = g_list_concat (llink, list);
501 * ]|
502 *
503 * Returns: the start of the new #GList, which equals @list1 if not %NULL
504 */
505 GList *
g_list_concat(GList * list1,GList * list2)506 g_list_concat (GList *list1,
507 GList *list2)
508 {
509 GList *tmp_list;
510
511 if (list2)
512 {
513 tmp_list = g_list_last (list1);
514 if (tmp_list)
515 tmp_list->next = list2;
516 else
517 list1 = list2;
518 list2->prev = tmp_list;
519 }
520
521 return list1;
522 }
523
524 static inline GList *
_g_list_remove_link(GList * list,GList * link)525 _g_list_remove_link (GList *list,
526 GList *link)
527 {
528 if (link == NULL)
529 return list;
530
531 if (link->prev)
532 {
533 if (link->prev->next == link)
534 link->prev->next = link->next;
535 else
536 g_warning ("corrupted double-linked list detected");
537 }
538 if (link->next)
539 {
540 if (link->next->prev == link)
541 link->next->prev = link->prev;
542 else
543 g_warning ("corrupted double-linked list detected");
544 }
545
546 if (link == list)
547 list = list->next;
548
549 link->next = NULL;
550 link->prev = NULL;
551
552 return list;
553 }
554
555 /**
556 * g_list_remove:
557 * @list: a #GList, this must point to the top of the list
558 * @data: the data of the element to remove
559 *
560 * Removes an element from a #GList.
561 * If two elements contain the same data, only the first is removed.
562 * If none of the elements contain the data, the #GList is unchanged.
563 *
564 * Returns: the (possibly changed) start of the #GList
565 */
566 GList *
g_list_remove(GList * list,gconstpointer data)567 g_list_remove (GList *list,
568 gconstpointer data)
569 {
570 GList *tmp;
571
572 tmp = list;
573 while (tmp)
574 {
575 if (tmp->data != data)
576 tmp = tmp->next;
577 else
578 {
579 list = _g_list_remove_link (list, tmp);
580 _g_list_free1 (tmp);
581
582 break;
583 }
584 }
585 return list;
586 }
587
588 /**
589 * g_list_remove_all:
590 * @list: a #GList, this must point to the top of the list
591 * @data: data to remove
592 *
593 * Removes all list nodes with data equal to @data.
594 * Returns the new head of the list. Contrast with
595 * g_list_remove() which removes only the first node
596 * matching the given data.
597 *
598 * Returns: the (possibly changed) start of the #GList
599 */
600 GList *
g_list_remove_all(GList * list,gconstpointer data)601 g_list_remove_all (GList *list,
602 gconstpointer data)
603 {
604 GList *tmp = list;
605
606 while (tmp)
607 {
608 if (tmp->data != data)
609 tmp = tmp->next;
610 else
611 {
612 GList *next = tmp->next;
613
614 if (tmp->prev)
615 tmp->prev->next = next;
616 else
617 list = next;
618 if (next)
619 next->prev = tmp->prev;
620
621 _g_list_free1 (tmp);
622 tmp = next;
623 }
624 }
625 return list;
626 }
627
628 /**
629 * g_list_remove_link:
630 * @list: a #GList, this must point to the top of the list
631 * @llink: an element in the #GList
632 *
633 * Removes an element from a #GList, without freeing the element.
634 * The removed element's prev and next links are set to %NULL, so
635 * that it becomes a self-contained list with one element.
636 *
637 * This function is for example used to move an element in the list
638 * (see the example for g_list_concat()) or to remove an element in
639 * the list before freeing its data:
640 * |[<!-- language="C" -->
641 * list = g_list_remove_link (list, llink);
642 * free_some_data_that_may_access_the_list_again (llink->data);
643 * g_list_free (llink);
644 * ]|
645 *
646 * Returns: the (possibly changed) start of the #GList
647 */
648 GList *
g_list_remove_link(GList * list,GList * llink)649 g_list_remove_link (GList *list,
650 GList *llink)
651 {
652 return _g_list_remove_link (list, llink);
653 }
654
655 /**
656 * g_list_delete_link:
657 * @list: a #GList, this must point to the top of the list
658 * @link_: node to delete from @list
659 *
660 * Removes the node link_ from the list and frees it.
661 * Compare this to g_list_remove_link() which removes the node
662 * without freeing it.
663 *
664 * Returns: the (possibly changed) start of the #GList
665 */
666 GList *
g_list_delete_link(GList * list,GList * link_)667 g_list_delete_link (GList *list,
668 GList *link_)
669 {
670 list = _g_list_remove_link (list, link_);
671 _g_list_free1 (link_);
672
673 return list;
674 }
675
676 /**
677 * g_list_copy:
678 * @list: a #GList, this must point to the top of the list
679 *
680 * Copies a #GList.
681 *
682 * Note that this is a "shallow" copy. If the list elements
683 * consist of pointers to data, the pointers are copied but
684 * the actual data is not. See g_list_copy_deep() if you need
685 * to copy the data as well.
686 *
687 * Returns: the start of the new list that holds the same data as @list
688 */
689 GList *
g_list_copy(GList * list)690 g_list_copy (GList *list)
691 {
692 return g_list_copy_deep (list, NULL, NULL);
693 }
694
695 /**
696 * g_list_copy_deep:
697 * @list: a #GList, this must point to the top of the list
698 * @func: a copy function used to copy every element in the list
699 * @user_data: user data passed to the copy function @func, or %NULL
700 *
701 * Makes a full (deep) copy of a #GList.
702 *
703 * In contrast with g_list_copy(), this function uses @func to make
704 * a copy of each list element, in addition to copying the list
705 * container itself.
706 *
707 * @func, as a #GCopyFunc, takes two arguments, the data to be copied
708 * and a @user_data pointer. On common processor architectures, it's safe to
709 * pass %NULL as @user_data if the copy function takes only one argument. You
710 * may get compiler warnings from this though if compiling with GCC’s
711 * `-Wcast-function-type` warning.
712 *
713 * For instance, if @list holds a list of GObjects, you can do:
714 * |[<!-- language="C" -->
715 * another_list = g_list_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
716 * ]|
717 *
718 * And, to entirely free the new list, you could do:
719 * |[<!-- language="C" -->
720 * g_list_free_full (another_list, g_object_unref);
721 * ]|
722 *
723 * Returns: the start of the new list that holds a full copy of @list,
724 * use g_list_free_full() to free it
725 *
726 * Since: 2.34
727 */
728 GList *
g_list_copy_deep(GList * list,GCopyFunc func,gpointer user_data)729 g_list_copy_deep (GList *list,
730 GCopyFunc func,
731 gpointer user_data)
732 {
733 GList *new_list = NULL;
734
735 if (list)
736 {
737 GList *last;
738
739 new_list = _g_list_alloc ();
740 if (func)
741 new_list->data = func (list->data, user_data);
742 else
743 new_list->data = list->data;
744 new_list->prev = NULL;
745 last = new_list;
746 list = list->next;
747 while (list)
748 {
749 last->next = _g_list_alloc ();
750 last->next->prev = last;
751 last = last->next;
752 if (func)
753 last->data = func (list->data, user_data);
754 else
755 last->data = list->data;
756 list = list->next;
757 }
758 last->next = NULL;
759 }
760
761 return new_list;
762 }
763
764 /**
765 * g_list_reverse:
766 * @list: a #GList, this must point to the top of the list
767 *
768 * Reverses a #GList.
769 * It simply switches the next and prev pointers of each element.
770 *
771 * Returns: the start of the reversed #GList
772 */
773 GList *
g_list_reverse(GList * list)774 g_list_reverse (GList *list)
775 {
776 GList *last;
777
778 last = NULL;
779 while (list)
780 {
781 last = list;
782 list = last->next;
783 last->next = last->prev;
784 last->prev = list;
785 }
786
787 return last;
788 }
789
790 /**
791 * g_list_nth:
792 * @list: a #GList, this must point to the top of the list
793 * @n: the position of the element, counting from 0
794 *
795 * Gets the element at the given position in a #GList.
796 *
797 * This iterates over the list until it reaches the @n-th position. If you
798 * intend to iterate over every element, it is better to use a for-loop as
799 * described in the #GList introduction.
800 *
801 * Returns: the element, or %NULL if the position is off
802 * the end of the #GList
803 */
804 GList *
g_list_nth(GList * list,guint n)805 g_list_nth (GList *list,
806 guint n)
807 {
808 while ((n-- > 0) && list)
809 list = list->next;
810
811 return list;
812 }
813
814 /**
815 * g_list_nth_prev:
816 * @list: a #GList
817 * @n: the position of the element, counting from 0
818 *
819 * Gets the element @n places before @list.
820 *
821 * Returns: the element, or %NULL if the position is
822 * off the end of the #GList
823 */
824 GList *
g_list_nth_prev(GList * list,guint n)825 g_list_nth_prev (GList *list,
826 guint n)
827 {
828 while ((n-- > 0) && list)
829 list = list->prev;
830
831 return list;
832 }
833
834 /**
835 * g_list_nth_data:
836 * @list: a #GList, this must point to the top of the list
837 * @n: the position of the element
838 *
839 * Gets the data of the element at the given position.
840 *
841 * This iterates over the list until it reaches the @n-th position. If you
842 * intend to iterate over every element, it is better to use a for-loop as
843 * described in the #GList introduction.
844 *
845 * Returns: the element's data, or %NULL if the position
846 * is off the end of the #GList
847 */
848 gpointer
g_list_nth_data(GList * list,guint n)849 g_list_nth_data (GList *list,
850 guint n)
851 {
852 while ((n-- > 0) && list)
853 list = list->next;
854
855 return list ? list->data : NULL;
856 }
857
858 /**
859 * g_list_find:
860 * @list: a #GList, this must point to the top of the list
861 * @data: the element data to find
862 *
863 * Finds the element in a #GList which contains the given data.
864 *
865 * Returns: the found #GList element, or %NULL if it is not found
866 */
867 GList *
g_list_find(GList * list,gconstpointer data)868 g_list_find (GList *list,
869 gconstpointer data)
870 {
871 while (list)
872 {
873 if (list->data == data)
874 break;
875 list = list->next;
876 }
877
878 return list;
879 }
880
881 /**
882 * g_list_find_custom:
883 * @list: a #GList, this must point to the top of the list
884 * @data: user data passed to the function
885 * @func: the function to call for each element.
886 * It should return 0 when the desired element is found
887 *
888 * Finds an element in a #GList, using a supplied function to
889 * find the desired element. It iterates over the list, calling
890 * the given function which should return 0 when the desired
891 * element is found. The function takes two #gconstpointer arguments,
892 * the #GList element's data as the first argument and the
893 * given user data.
894 *
895 * Returns: the found #GList element, or %NULL if it is not found
896 */
897 GList *
g_list_find_custom(GList * list,gconstpointer data,GCompareFunc func)898 g_list_find_custom (GList *list,
899 gconstpointer data,
900 GCompareFunc func)
901 {
902 g_return_val_if_fail (func != NULL, list);
903
904 while (list)
905 {
906 if (! func (list->data, data))
907 return list;
908 list = list->next;
909 }
910
911 return NULL;
912 }
913
914 /**
915 * g_list_position:
916 * @list: a #GList, this must point to the top of the list
917 * @llink: an element in the #GList
918 *
919 * Gets the position of the given element
920 * in the #GList (starting from 0).
921 *
922 * Returns: the position of the element in the #GList,
923 * or -1 if the element is not found
924 */
925 gint
g_list_position(GList * list,GList * llink)926 g_list_position (GList *list,
927 GList *llink)
928 {
929 gint i;
930
931 i = 0;
932 while (list)
933 {
934 if (list == llink)
935 return i;
936 i++;
937 list = list->next;
938 }
939
940 return -1;
941 }
942
943 /**
944 * g_list_index:
945 * @list: a #GList, this must point to the top of the list
946 * @data: the data to find
947 *
948 * Gets the position of the element containing
949 * the given data (starting from 0).
950 *
951 * Returns: the index of the element containing the data,
952 * or -1 if the data is not found
953 */
954 gint
g_list_index(GList * list,gconstpointer data)955 g_list_index (GList *list,
956 gconstpointer data)
957 {
958 gint i;
959
960 i = 0;
961 while (list)
962 {
963 if (list->data == data)
964 return i;
965 i++;
966 list = list->next;
967 }
968
969 return -1;
970 }
971
972 /**
973 * g_list_last:
974 * @list: any #GList element
975 *
976 * Gets the last element in a #GList.
977 *
978 * Returns: the last element in the #GList,
979 * or %NULL if the #GList has no elements
980 */
981 GList *
g_list_last(GList * list)982 g_list_last (GList *list)
983 {
984 if (list)
985 {
986 while (list->next)
987 list = list->next;
988 }
989
990 return list;
991 }
992
993 /**
994 * g_list_first:
995 * @list: any #GList element
996 *
997 * Gets the first element in a #GList.
998 *
999 * Returns: the first element in the #GList,
1000 * or %NULL if the #GList has no elements
1001 */
1002 GList *
g_list_first(GList * list)1003 g_list_first (GList *list)
1004 {
1005 if (list)
1006 {
1007 while (list->prev)
1008 list = list->prev;
1009 }
1010
1011 return list;
1012 }
1013
1014 /**
1015 * g_list_length:
1016 * @list: a #GList, this must point to the top of the list
1017 *
1018 * Gets the number of elements in a #GList.
1019 *
1020 * This function iterates over the whole list to count its elements.
1021 * Use a #GQueue instead of a GList if you regularly need the number
1022 * of items. To check whether the list is non-empty, it is faster to check
1023 * @list against %NULL.
1024 *
1025 * Returns: the number of elements in the #GList
1026 */
1027 guint
g_list_length(GList * list)1028 g_list_length (GList *list)
1029 {
1030 guint length;
1031
1032 length = 0;
1033 while (list)
1034 {
1035 length++;
1036 list = list->next;
1037 }
1038
1039 return length;
1040 }
1041
1042 /**
1043 * g_list_foreach:
1044 * @list: a #GList, this must point to the top of the list
1045 * @func: the function to call with each element's data
1046 * @user_data: user data to pass to the function
1047 *
1048 * Calls a function for each element of a #GList.
1049 *
1050 * It is safe for @func to remove the element from @list, but it must
1051 * not modify any part of the list after that element.
1052 */
1053 /**
1054 * GFunc:
1055 * @data: the element's data
1056 * @user_data: user data passed to g_list_foreach() or g_slist_foreach()
1057 *
1058 * Specifies the type of functions passed to g_list_foreach() and
1059 * g_slist_foreach().
1060 */
1061 void
g_list_foreach(GList * list,GFunc func,gpointer user_data)1062 g_list_foreach (GList *list,
1063 GFunc func,
1064 gpointer user_data)
1065 {
1066 while (list)
1067 {
1068 GList *next = list->next;
1069 (*func) (list->data, user_data);
1070 list = next;
1071 }
1072 }
1073
1074 static GList*
g_list_insert_sorted_real(GList * list,gpointer data,GFunc func,gpointer user_data)1075 g_list_insert_sorted_real (GList *list,
1076 gpointer data,
1077 GFunc func,
1078 gpointer user_data)
1079 {
1080 GList *tmp_list = list;
1081 GList *new_list;
1082 gint cmp;
1083
1084 g_return_val_if_fail (func != NULL, list);
1085
1086 if (!list)
1087 {
1088 new_list = _g_list_alloc0 ();
1089 new_list->data = data;
1090 return new_list;
1091 }
1092
1093 cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
1094
1095 while ((tmp_list->next) && (cmp > 0))
1096 {
1097 tmp_list = tmp_list->next;
1098
1099 cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
1100 }
1101
1102 new_list = _g_list_alloc0 ();
1103 new_list->data = data;
1104
1105 if ((!tmp_list->next) && (cmp > 0))
1106 {
1107 tmp_list->next = new_list;
1108 new_list->prev = tmp_list;
1109 return list;
1110 }
1111
1112 if (tmp_list->prev)
1113 {
1114 tmp_list->prev->next = new_list;
1115 new_list->prev = tmp_list->prev;
1116 }
1117 new_list->next = tmp_list;
1118 tmp_list->prev = new_list;
1119
1120 if (tmp_list == list)
1121 return new_list;
1122 else
1123 return list;
1124 }
1125
1126 /**
1127 * g_list_insert_sorted:
1128 * @list: a pointer to a #GList, this must point to the top of the
1129 * already sorted list
1130 * @data: the data for the new element
1131 * @func: the function to compare elements in the list. It should
1132 * return a number > 0 if the first parameter comes after the
1133 * second parameter in the sort order.
1134 *
1135 * Inserts a new element into the list, using the given comparison
1136 * function to determine its position.
1137 *
1138 * If you are adding many new elements to a list, and the number of
1139 * new elements is much larger than the length of the list, use
1140 * g_list_prepend() to add the new items and sort the list afterwards
1141 * with g_list_sort().
1142 *
1143 * Returns: the (possibly changed) start of the #GList
1144 */
1145 GList *
g_list_insert_sorted(GList * list,gpointer data,GCompareFunc func)1146 g_list_insert_sorted (GList *list,
1147 gpointer data,
1148 GCompareFunc func)
1149 {
1150 return g_list_insert_sorted_real (list, data, (GFunc) func, NULL);
1151 }
1152
1153 /**
1154 * g_list_insert_sorted_with_data:
1155 * @list: a pointer to a #GList, this must point to the top of the
1156 * already sorted list
1157 * @data: the data for the new element
1158 * @func: the function to compare elements in the list. It should
1159 * return a number > 0 if the first parameter comes after the
1160 * second parameter in the sort order.
1161 * @user_data: user data to pass to comparison function
1162 *
1163 * Inserts a new element into the list, using the given comparison
1164 * function to determine its position.
1165 *
1166 * If you are adding many new elements to a list, and the number of
1167 * new elements is much larger than the length of the list, use
1168 * g_list_prepend() to add the new items and sort the list afterwards
1169 * with g_list_sort().
1170 *
1171 * Returns: the (possibly changed) start of the #GList
1172 *
1173 * Since: 2.10
1174 */
1175 GList *
g_list_insert_sorted_with_data(GList * list,gpointer data,GCompareDataFunc func,gpointer user_data)1176 g_list_insert_sorted_with_data (GList *list,
1177 gpointer data,
1178 GCompareDataFunc func,
1179 gpointer user_data)
1180 {
1181 return g_list_insert_sorted_real (list, data, (GFunc) func, user_data);
1182 }
1183
1184 static GList *
g_list_sort_merge(GList * l1,GList * l2,GFunc compare_func,gpointer user_data)1185 g_list_sort_merge (GList *l1,
1186 GList *l2,
1187 GFunc compare_func,
1188 gpointer user_data)
1189 {
1190 GList list, *l, *lprev;
1191 gint cmp;
1192
1193 l = &list;
1194 lprev = NULL;
1195
1196 while (l1 && l2)
1197 {
1198 cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
1199
1200 if (cmp <= 0)
1201 {
1202 l->next = l1;
1203 l1 = l1->next;
1204 }
1205 else
1206 {
1207 l->next = l2;
1208 l2 = l2->next;
1209 }
1210 l = l->next;
1211 l->prev = lprev;
1212 lprev = l;
1213 }
1214 l->next = l1 ? l1 : l2;
1215 l->next->prev = l;
1216
1217 return list.next;
1218 }
1219
1220 static GList *
g_list_sort_real(GList * list,GFunc compare_func,gpointer user_data)1221 g_list_sort_real (GList *list,
1222 GFunc compare_func,
1223 gpointer user_data)
1224 {
1225 GList *l1, *l2;
1226
1227 if (!list)
1228 return NULL;
1229 if (!list->next)
1230 return list;
1231
1232 l1 = list;
1233 l2 = list->next;
1234
1235 while ((l2 = l2->next) != NULL)
1236 {
1237 if ((l2 = l2->next) == NULL)
1238 break;
1239 l1 = l1->next;
1240 }
1241 l2 = l1->next;
1242 l1->next = NULL;
1243
1244 return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data),
1245 g_list_sort_real (l2, compare_func, user_data),
1246 compare_func,
1247 user_data);
1248 }
1249
1250 /**
1251 * g_list_sort:
1252 * @list: a #GList, this must point to the top of the list
1253 * @compare_func: the comparison function used to sort the #GList.
1254 * This function is passed the data from 2 elements of the #GList
1255 * and should return 0 if they are equal, a negative value if the
1256 * first element comes before the second, or a positive value if
1257 * the first element comes after the second.
1258 *
1259 * Sorts a #GList using the given comparison function. The algorithm
1260 * used is a stable sort.
1261 *
1262 * Returns: the (possibly changed) start of the #GList
1263 */
1264 /**
1265 * GCompareFunc:
1266 * @a: a value
1267 * @b: a value to compare with
1268 *
1269 * Specifies the type of a comparison function used to compare two
1270 * values. The function should return a negative integer if the first
1271 * value comes before the second, 0 if they are equal, or a positive
1272 * integer if the first value comes after the second.
1273 *
1274 * Returns: negative value if @a < @b; zero if @a = @b; positive
1275 * value if @a > @b
1276 */
1277 GList *
g_list_sort(GList * list,GCompareFunc compare_func)1278 g_list_sort (GList *list,
1279 GCompareFunc compare_func)
1280 {
1281 return g_list_sort_real (list, (GFunc) compare_func, NULL);
1282 }
1283
1284 /**
1285 * g_list_sort_with_data:
1286 * @list: a #GList, this must point to the top of the list
1287 * @compare_func: comparison function
1288 * @user_data: user data to pass to comparison function
1289 *
1290 * Like g_list_sort(), but the comparison function accepts
1291 * a user data argument.
1292 *
1293 * Returns: the (possibly changed) start of the #GList
1294 */
1295 /**
1296 * GCompareDataFunc:
1297 * @a: a value
1298 * @b: a value to compare with
1299 * @user_data: user data
1300 *
1301 * Specifies the type of a comparison function used to compare two
1302 * values. The function should return a negative integer if the first
1303 * value comes before the second, 0 if they are equal, or a positive
1304 * integer if the first value comes after the second.
1305 *
1306 * Returns: negative value if @a < @b; zero if @a = @b; positive
1307 * value if @a > @b
1308 */
1309 GList *
g_list_sort_with_data(GList * list,GCompareDataFunc compare_func,gpointer user_data)1310 g_list_sort_with_data (GList *list,
1311 GCompareDataFunc compare_func,
1312 gpointer user_data)
1313 {
1314 return g_list_sort_real (list, (GFunc) compare_func, user_data);
1315 }
1316