• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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