• 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 "gslist.h"
32 
33 #include "gtestutils.h"
34 #include "gslice.h"
35 
36 /**
37  * SECTION:linked_lists_single
38  * @title: Singly-Linked Lists
39  * @short_description: linked lists that can be iterated in one direction
40  *
41  * The #GSList structure and its associated functions provide a
42  * standard singly-linked list data structure.
43  *
44  * Each element in the list contains a piece of data, together with a
45  * pointer which links to the next element in the list. Using this
46  * pointer it is possible to move through the list in one direction
47  * only (unlike the [double-linked lists][glib-Doubly-Linked-Lists],
48  * which allow movement in both directions).
49  *
50  * The data contained in each element can be either integer values, by
51  * using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
52  * or simply pointers to any type of data.
53  *
54  * List elements are allocated from the [slice allocator][glib-Memory-Slices],
55  * which is more efficient than allocating elements individually.
56  *
57  * Note that most of the #GSList functions expect to be passed a
58  * pointer to the first element in the list. The functions which insert
59  * elements return the new start of the list, which may have changed.
60  *
61  * There is no function to create a #GSList. %NULL is considered to be
62  * the empty list so you simply set a #GSList* to %NULL.
63  *
64  * To add elements, use g_slist_append(), g_slist_prepend(),
65  * g_slist_insert() and g_slist_insert_sorted().
66  *
67  * To remove elements, use g_slist_remove().
68  *
69  * To find elements in the list use g_slist_last(), g_slist_next(),
70  * g_slist_nth(), g_slist_nth_data(), g_slist_find() and
71  * g_slist_find_custom().
72  *
73  * To find the index of an element use g_slist_position() and
74  * g_slist_index().
75  *
76  * To call a function for each element in the list use
77  * g_slist_foreach().
78  *
79  * To free the entire list, use g_slist_free().
80  **/
81 
82 /**
83  * GSList:
84  * @data: holds the element's data, which can be a pointer to any kind
85  *        of data, or any integer value using the
86  *        [Type Conversion Macros][glib-Type-Conversion-Macros]
87  * @next: contains the link to the next element in the list.
88  *
89  * The #GSList struct is used for each element in the singly-linked
90  * list.
91  **/
92 
93 /**
94  * g_slist_next:
95  * @slist: an element in a #GSList.
96  *
97  * A convenience macro to get the next element in a #GSList.
98  * Note that it is considered perfectly acceptable to access
99  * @slist->next directly.
100  *
101  * Returns: the next element, or %NULL if there are no more elements.
102  **/
103 
104 #define _g_slist_alloc0()       g_slice_new0 (GSList)
105 #define _g_slist_alloc()        g_slice_new (GSList)
106 #define _g_slist_free1(slist)   g_slice_free (GSList, slist)
107 
108 /**
109  * g_slist_alloc:
110  *
111  * Allocates space for one #GSList element. It is called by the
112  * g_slist_append(), g_slist_prepend(), g_slist_insert() and
113  * g_slist_insert_sorted() functions and so is rarely used on its own.
114  *
115  * Returns: a pointer to the newly-allocated #GSList element.
116  **/
117 GSList*
g_slist_alloc(void)118 g_slist_alloc (void)
119 {
120   return _g_slist_alloc0 ();
121 }
122 
123 /**
124  * g_slist_free:
125  * @list: a #GSList
126  *
127  * Frees all of the memory used by a #GSList.
128  * The freed elements are returned to the slice allocator.
129  *
130  * If list elements contain dynamically-allocated memory,
131  * you should either use g_slist_free_full() or free them manually
132  * first.
133  */
134 void
g_slist_free(GSList * list)135 g_slist_free (GSList *list)
136 {
137   g_slice_free_chain (GSList, list, next);
138 }
139 
140 /**
141  * g_slist_free_1:
142  * @list: a #GSList element
143  *
144  * Frees one #GSList element.
145  * It is usually used after g_slist_remove_link().
146  */
147 /**
148  * g_slist_free1:
149  *
150  * A macro which does the same as g_slist_free_1().
151  *
152  * Since: 2.10
153  **/
154 void
g_slist_free_1(GSList * list)155 g_slist_free_1 (GSList *list)
156 {
157   _g_slist_free1 (list);
158 }
159 
160 /**
161  * g_slist_free_full:
162  * @list: a pointer to a #GSList
163  * @free_func: the function to be called to free each element's data
164  *
165  * Convenience method, which frees all the memory used by a #GSList, and
166  * calls the specified destroy function on every element's data.
167  *
168  * @free_func must not modify the list (eg, by removing the freed
169  * element from it).
170  *
171  * Since: 2.28
172  **/
173 void
g_slist_free_full(GSList * list,GDestroyNotify free_func)174 g_slist_free_full (GSList         *list,
175 		   GDestroyNotify  free_func)
176 {
177   g_slist_foreach (list, (GFunc) free_func, NULL);
178   g_slist_free (list);
179 }
180 
181 /**
182  * g_slist_append:
183  * @list: a #GSList
184  * @data: the data for the new element
185  *
186  * Adds a new element on to the end of the list.
187  *
188  * The return value is the new start of the list, which may
189  * have changed, so make sure you store the new value.
190  *
191  * Note that g_slist_append() has to traverse the entire list
192  * to find the end, which is inefficient when adding multiple
193  * elements. A common idiom to avoid the inefficiency is to prepend
194  * the elements and reverse the list when all elements have been added.
195  *
196  * |[<!-- language="C" -->
197  * // Notice that these are initialized to the empty list.
198  * GSList *list = NULL, *number_list = NULL;
199  *
200  * // This is a list of strings.
201  * list = g_slist_append (list, "first");
202  * list = g_slist_append (list, "second");
203  *
204  * // This is a list of integers.
205  * number_list = g_slist_append (number_list, GINT_TO_POINTER (27));
206  * number_list = g_slist_append (number_list, GINT_TO_POINTER (14));
207  * ]|
208  *
209  * Returns: the new start of the #GSList
210  */
211 GSList*
g_slist_append(GSList * list,gpointer data)212 g_slist_append (GSList   *list,
213                 gpointer  data)
214 {
215   GSList *new_list;
216   GSList *last;
217 
218   new_list = _g_slist_alloc ();
219   new_list->data = data;
220   new_list->next = NULL;
221 
222   if (list)
223     {
224       last = g_slist_last (list);
225       /* g_assert (last != NULL); */
226       last->next = new_list;
227 
228       return list;
229     }
230   else
231     return new_list;
232 }
233 
234 /**
235  * g_slist_prepend:
236  * @list: a #GSList
237  * @data: the data for the new element
238  *
239  * Adds a new element on to the start of the list.
240  *
241  * The return value is the new start of the list, which
242  * may have changed, so make sure you store the new value.
243  *
244  * |[<!-- language="C" -->
245  * // Notice that it is initialized to the empty list.
246  * GSList *list = NULL;
247  * list = g_slist_prepend (list, "last");
248  * list = g_slist_prepend (list, "first");
249  * ]|
250  *
251  * Returns: the new start of the #GSList
252  */
253 GSList*
g_slist_prepend(GSList * list,gpointer data)254 g_slist_prepend (GSList   *list,
255                  gpointer  data)
256 {
257   GSList *new_list;
258 
259   new_list = _g_slist_alloc ();
260   new_list->data = data;
261   new_list->next = list;
262 
263   return new_list;
264 }
265 
266 /**
267  * g_slist_insert:
268  * @list: a #GSList
269  * @data: the data for the new element
270  * @position: the position to insert the element.
271  *     If this is negative, or is larger than the number
272  *     of elements in the list, the new element is added on
273  *     to the end of the list.
274  *
275  * Inserts a new element into the list at the given position.
276  *
277  * Returns: the new start of the #GSList
278  */
279 GSList*
g_slist_insert(GSList * list,gpointer data,gint position)280 g_slist_insert (GSList   *list,
281                 gpointer  data,
282                 gint      position)
283 {
284   GSList *prev_list;
285   GSList *tmp_list;
286   GSList *new_list;
287 
288   if (position < 0)
289     return g_slist_append (list, data);
290   else if (position == 0)
291     return g_slist_prepend (list, data);
292 
293   new_list = _g_slist_alloc ();
294   new_list->data = data;
295 
296   if (!list)
297     {
298       new_list->next = NULL;
299       return new_list;
300     }
301 
302   prev_list = NULL;
303   tmp_list = list;
304 
305   while ((position-- > 0) && tmp_list)
306     {
307       prev_list = tmp_list;
308       tmp_list = tmp_list->next;
309     }
310 
311   new_list->next = prev_list->next;
312   prev_list->next = new_list;
313 
314   return list;
315 }
316 
317 /**
318  * g_slist_insert_before:
319  * @slist: a #GSList
320  * @sibling: node to insert @data before
321  * @data: data to put in the newly-inserted node
322  *
323  * Inserts a node before @sibling containing @data.
324  *
325  * Returns: the new head of the list.
326  */
327 GSList*
g_slist_insert_before(GSList * slist,GSList * sibling,gpointer data)328 g_slist_insert_before (GSList  *slist,
329                        GSList  *sibling,
330                        gpointer data)
331 {
332   if (!slist)
333     {
334       slist = _g_slist_alloc ();
335       slist->data = data;
336       slist->next = NULL;
337       g_return_val_if_fail (sibling == NULL, slist);
338       return slist;
339     }
340   else
341     {
342       GSList *node, *last = NULL;
343 
344       for (node = slist; node; last = node, node = last->next)
345         if (node == sibling)
346           break;
347       if (!last)
348         {
349           node = _g_slist_alloc ();
350           node->data = data;
351           node->next = slist;
352 
353           return node;
354         }
355       else
356         {
357           node = _g_slist_alloc ();
358           node->data = data;
359           node->next = last->next;
360           last->next = node;
361 
362           return slist;
363         }
364     }
365 }
366 
367 /**
368  * g_slist_concat:
369  * @list1: a #GSList
370  * @list2: the #GSList to add to the end of the first #GSList
371  *
372  * Adds the second #GSList onto the end of the first #GSList.
373  * Note that the elements of the second #GSList are not copied.
374  * They are used directly.
375  *
376  * Returns: the start of the new #GSList
377  */
378 GSList *
g_slist_concat(GSList * list1,GSList * list2)379 g_slist_concat (GSList *list1, GSList *list2)
380 {
381   if (list2)
382     {
383       if (list1)
384         g_slist_last (list1)->next = list2;
385       else
386         list1 = list2;
387     }
388 
389   return list1;
390 }
391 
392 static GSList*
_g_slist_remove_data(GSList * list,gconstpointer data,gboolean all)393 _g_slist_remove_data (GSList        *list,
394                       gconstpointer  data,
395                       gboolean       all)
396 {
397   GSList *tmp = NULL;
398   GSList **previous_ptr = &list;
399 
400   while (*previous_ptr)
401     {
402       tmp = *previous_ptr;
403       if (tmp->data == data)
404         {
405           *previous_ptr = tmp->next;
406           g_slist_free_1 (tmp);
407           if (!all)
408             break;
409         }
410       else
411         {
412           previous_ptr = &tmp->next;
413         }
414     }
415 
416   return list;
417 }
418 /**
419  * g_slist_remove:
420  * @list: a #GSList
421  * @data: the data of the element to remove
422  *
423  * Removes an element from a #GSList.
424  * If two elements contain the same data, only the first is removed.
425  * If none of the elements contain the data, the #GSList is unchanged.
426  *
427  * Returns: the new start of the #GSList
428  */
429 GSList*
g_slist_remove(GSList * list,gconstpointer data)430 g_slist_remove (GSList        *list,
431                 gconstpointer  data)
432 {
433   return _g_slist_remove_data (list, data, FALSE);
434 }
435 
436 /**
437  * g_slist_remove_all:
438  * @list: a #GSList
439  * @data: data to remove
440  *
441  * Removes all list nodes with data equal to @data.
442  * Returns the new head of the list. Contrast with
443  * g_slist_remove() which removes only the first node
444  * matching the given data.
445  *
446  * Returns: new head of @list
447  */
448 GSList*
g_slist_remove_all(GSList * list,gconstpointer data)449 g_slist_remove_all (GSList        *list,
450                     gconstpointer  data)
451 {
452   return _g_slist_remove_data (list, data, TRUE);
453 }
454 
455 static inline GSList*
_g_slist_remove_link(GSList * list,GSList * link)456 _g_slist_remove_link (GSList *list,
457                       GSList *link)
458 {
459   GSList *tmp = NULL;
460   GSList **previous_ptr = &list;
461 
462   while (*previous_ptr)
463     {
464       tmp = *previous_ptr;
465       if (tmp == link)
466         {
467           *previous_ptr = tmp->next;
468           tmp->next = NULL;
469           break;
470         }
471 
472       previous_ptr = &tmp->next;
473     }
474 
475   return list;
476 }
477 
478 /**
479  * g_slist_remove_link:
480  * @list: a #GSList
481  * @link_: an element in the #GSList
482  *
483  * Removes an element from a #GSList, without
484  * freeing the element. The removed element's next
485  * link is set to %NULL, so that it becomes a
486  * self-contained list with one element.
487  *
488  * Removing arbitrary nodes from a singly-linked list
489  * requires time that is proportional to the length of the list
490  * (ie. O(n)). If you find yourself using g_slist_remove_link()
491  * frequently, you should consider a different data structure,
492  * such as the doubly-linked #GList.
493  *
494  * Returns: the new start of the #GSList, without the element
495  */
496 GSList*
g_slist_remove_link(GSList * list,GSList * link_)497 g_slist_remove_link (GSList *list,
498                      GSList *link_)
499 {
500   return _g_slist_remove_link (list, link_);
501 }
502 
503 /**
504  * g_slist_delete_link:
505  * @list: a #GSList
506  * @link_: node to delete
507  *
508  * Removes the node link_ from the list and frees it.
509  * Compare this to g_slist_remove_link() which removes the node
510  * without freeing it.
511  *
512  * Removing arbitrary nodes from a singly-linked list requires time
513  * that is proportional to the length of the list (ie. O(n)). If you
514  * find yourself using g_slist_delete_link() frequently, you should
515  * consider a different data structure, such as the doubly-linked
516  * #GList.
517  *
518  * Returns: the new head of @list
519  */
520 GSList*
g_slist_delete_link(GSList * list,GSList * link_)521 g_slist_delete_link (GSList *list,
522                      GSList *link_)
523 {
524   list = _g_slist_remove_link (list, link_);
525   _g_slist_free1 (link_);
526 
527   return list;
528 }
529 
530 /**
531  * g_slist_copy:
532  * @list: a #GSList
533  *
534  * Copies a #GSList.
535  *
536  * Note that this is a "shallow" copy. If the list elements
537  * consist of pointers to data, the pointers are copied but
538  * the actual data isn't. See g_slist_copy_deep() if you need
539  * to copy the data as well.
540  *
541  * Returns: a copy of @list
542  */
543 GSList*
g_slist_copy(GSList * list)544 g_slist_copy (GSList *list)
545 {
546   return g_slist_copy_deep (list, NULL, NULL);
547 }
548 
549 /**
550  * g_slist_copy_deep:
551  * @list: a #GSList
552  * @func: a copy function used to copy every element in the list
553  * @user_data: user data passed to the copy function @func, or #NULL
554  *
555  * Makes a full (deep) copy of a #GSList.
556  *
557  * In contrast with g_slist_copy(), this function uses @func to make a copy of
558  * each list element, in addition to copying the list container itself.
559  *
560  * @func, as a #GCopyFunc, takes two arguments, the data to be copied
561  * and a @user_data pointer. On common processor architectures, it's safe to
562  * pass %NULL as @user_data if the copy function takes only one argument. You
563  * may get compiler warnings from this though if compiling with GCC’s
564  * `-Wcast-function-type` warning.
565  *
566  * For instance, if @list holds a list of GObjects, you can do:
567  * |[<!-- language="C" -->
568  * another_list = g_slist_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
569  * ]|
570  *
571  * And, to entirely free the new list, you could do:
572  * |[<!-- language="C" -->
573  * g_slist_free_full (another_list, g_object_unref);
574  * ]|
575  *
576  * Returns: a full copy of @list, use g_slist_free_full() to free it
577  *
578  * Since: 2.34
579  */
580 GSList*
g_slist_copy_deep(GSList * list,GCopyFunc func,gpointer user_data)581 g_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data)
582 {
583   GSList *new_list = NULL;
584 
585   if (list)
586     {
587       GSList *last;
588 
589       new_list = _g_slist_alloc ();
590       if (func)
591         new_list->data = func (list->data, user_data);
592       else
593         new_list->data = list->data;
594       last = new_list;
595       list = list->next;
596       while (list)
597         {
598           last->next = _g_slist_alloc ();
599           last = last->next;
600           if (func)
601             last->data = func (list->data, user_data);
602           else
603             last->data = list->data;
604           list = list->next;
605         }
606       last->next = NULL;
607     }
608 
609   return new_list;
610 }
611 
612 /**
613  * g_slist_reverse:
614  * @list: a #GSList
615  *
616  * Reverses a #GSList.
617  *
618  * Returns: the start of the reversed #GSList
619  */
620 GSList*
g_slist_reverse(GSList * list)621 g_slist_reverse (GSList *list)
622 {
623   GSList *prev = NULL;
624 
625   while (list)
626     {
627       GSList *next = list->next;
628 
629       list->next = prev;
630 
631       prev = list;
632       list = next;
633     }
634 
635   return prev;
636 }
637 
638 /**
639  * g_slist_nth:
640  * @list: a #GSList
641  * @n: the position of the element, counting from 0
642  *
643  * Gets the element at the given position in a #GSList.
644  *
645  * Returns: the element, or %NULL if the position is off
646  *     the end of the #GSList
647  */
648 GSList*
g_slist_nth(GSList * list,guint n)649 g_slist_nth (GSList *list,
650              guint   n)
651 {
652   while (n-- > 0 && list)
653     list = list->next;
654 
655   return list;
656 }
657 
658 /**
659  * g_slist_nth_data:
660  * @list: a #GSList
661  * @n: the position of the element
662  *
663  * Gets the data of the element at the given position.
664  *
665  * Returns: the element's data, or %NULL if the position
666  *     is off the end of the #GSList
667  */
668 gpointer
g_slist_nth_data(GSList * list,guint n)669 g_slist_nth_data (GSList   *list,
670                   guint     n)
671 {
672   while (n-- > 0 && list)
673     list = list->next;
674 
675   return list ? list->data : NULL;
676 }
677 
678 /**
679  * g_slist_find:
680  * @list: a #GSList
681  * @data: the element data to find
682  *
683  * Finds the element in a #GSList which
684  * contains the given data.
685  *
686  * Returns: the found #GSList element,
687  *     or %NULL if it is not found
688  */
689 GSList*
g_slist_find(GSList * list,gconstpointer data)690 g_slist_find (GSList        *list,
691               gconstpointer  data)
692 {
693   while (list)
694     {
695       if (list->data == data)
696         break;
697       list = list->next;
698     }
699 
700   return list;
701 }
702 
703 
704 /**
705  * g_slist_find_custom:
706  * @list: a #GSList
707  * @data: user data passed to the function
708  * @func: the function to call for each element.
709  *     It should return 0 when the desired element is found
710  *
711  * Finds an element in a #GSList, using a supplied function to
712  * find the desired element. It iterates over the list, calling
713  * the given function which should return 0 when the desired
714  * element is found. The function takes two #gconstpointer arguments,
715  * the #GSList element's data as the first argument and the
716  * given user data.
717  *
718  * Returns: the found #GSList element, or %NULL if it is not found
719  */
720 GSList*
g_slist_find_custom(GSList * list,gconstpointer data,GCompareFunc func)721 g_slist_find_custom (GSList        *list,
722                      gconstpointer  data,
723                      GCompareFunc   func)
724 {
725   g_return_val_if_fail (func != NULL, list);
726 
727   while (list)
728     {
729       if (! func (list->data, data))
730         return list;
731       list = list->next;
732     }
733 
734   return NULL;
735 }
736 
737 /**
738  * g_slist_position:
739  * @list: a #GSList
740  * @llink: an element in the #GSList
741  *
742  * Gets the position of the given element
743  * in the #GSList (starting from 0).
744  *
745  * Returns: the position of the element in the #GSList,
746  *     or -1 if the element is not found
747  */
748 gint
g_slist_position(GSList * list,GSList * llink)749 g_slist_position (GSList *list,
750                   GSList *llink)
751 {
752   gint i;
753 
754   i = 0;
755   while (list)
756     {
757       if (list == llink)
758         return i;
759       i++;
760       list = list->next;
761     }
762 
763   return -1;
764 }
765 
766 /**
767  * g_slist_index:
768  * @list: a #GSList
769  * @data: the data to find
770  *
771  * Gets the position of the element containing
772  * the given data (starting from 0).
773  *
774  * Returns: the index of the element containing the data,
775  *     or -1 if the data is not found
776  */
777 gint
g_slist_index(GSList * list,gconstpointer data)778 g_slist_index (GSList        *list,
779                gconstpointer  data)
780 {
781   gint i;
782 
783   i = 0;
784   while (list)
785     {
786       if (list->data == data)
787         return i;
788       i++;
789       list = list->next;
790     }
791 
792   return -1;
793 }
794 
795 /**
796  * g_slist_last:
797  * @list: a #GSList
798  *
799  * Gets the last element in a #GSList.
800  *
801  * This function iterates over the whole list.
802  *
803  * Returns: the last element in the #GSList,
804  *     or %NULL if the #GSList has no elements
805  */
806 GSList*
g_slist_last(GSList * list)807 g_slist_last (GSList *list)
808 {
809   if (list)
810     {
811       while (list->next)
812         list = list->next;
813     }
814 
815   return list;
816 }
817 
818 /**
819  * g_slist_length:
820  * @list: a #GSList
821  *
822  * Gets the number of elements in a #GSList.
823  *
824  * This function iterates over the whole list to
825  * count its elements. To check whether the list is non-empty, it is faster to
826  * check @list against %NULL.
827  *
828  * Returns: the number of elements in the #GSList
829  */
830 guint
g_slist_length(GSList * list)831 g_slist_length (GSList *list)
832 {
833   guint length;
834 
835   length = 0;
836   while (list)
837     {
838       length++;
839       list = list->next;
840     }
841 
842   return length;
843 }
844 
845 /**
846  * g_slist_foreach:
847  * @list: a #GSList
848  * @func: the function to call with each element's data
849  * @user_data: user data to pass to the function
850  *
851  * Calls a function for each element of a #GSList.
852  *
853  * It is safe for @func to remove the element from @list, but it must
854  * not modify any part of the list after that element.
855  */
856 void
g_slist_foreach(GSList * list,GFunc func,gpointer user_data)857 g_slist_foreach (GSList   *list,
858                  GFunc     func,
859                  gpointer  user_data)
860 {
861   while (list)
862     {
863       GSList *next = list->next;
864       (*func) (list->data, user_data);
865       list = next;
866     }
867 }
868 
869 static GSList*
g_slist_insert_sorted_real(GSList * list,gpointer data,GFunc func,gpointer user_data)870 g_slist_insert_sorted_real (GSList   *list,
871                             gpointer  data,
872                             GFunc     func,
873                             gpointer  user_data)
874 {
875   GSList *tmp_list = list;
876   GSList *prev_list = NULL;
877   GSList *new_list;
878   gint cmp;
879 
880   g_return_val_if_fail (func != NULL, list);
881 
882   if (!list)
883     {
884       new_list = _g_slist_alloc ();
885       new_list->data = data;
886       new_list->next = NULL;
887       return new_list;
888     }
889 
890   cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
891 
892   while ((tmp_list->next) && (cmp > 0))
893     {
894       prev_list = tmp_list;
895       tmp_list = tmp_list->next;
896 
897       cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
898     }
899 
900   new_list = _g_slist_alloc ();
901   new_list->data = data;
902 
903   if ((!tmp_list->next) && (cmp > 0))
904     {
905       tmp_list->next = new_list;
906       new_list->next = NULL;
907       return list;
908     }
909 
910   if (prev_list)
911     {
912       prev_list->next = new_list;
913       new_list->next = tmp_list;
914       return list;
915     }
916   else
917     {
918       new_list->next = list;
919       return new_list;
920     }
921 }
922 
923 /**
924  * g_slist_insert_sorted:
925  * @list: a #GSList
926  * @data: the data for the new element
927  * @func: the function to compare elements in the list.
928  *     It should return a number > 0 if the first parameter
929  *     comes after the second parameter in the sort order.
930  *
931  * Inserts a new element into the list, using the given
932  * comparison function to determine its position.
933  *
934  * Returns: the new start of the #GSList
935  */
936 GSList*
g_slist_insert_sorted(GSList * list,gpointer data,GCompareFunc func)937 g_slist_insert_sorted (GSList       *list,
938                        gpointer      data,
939                        GCompareFunc  func)
940 {
941   return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL);
942 }
943 
944 /**
945  * g_slist_insert_sorted_with_data:
946  * @list: a #GSList
947  * @data: the data for the new element
948  * @func: the function to compare elements in the list.
949  *     It should return a number > 0 if the first parameter
950  *     comes after the second parameter in the sort order.
951  * @user_data: data to pass to comparison function
952  *
953  * Inserts a new element into the list, using the given
954  * comparison function to determine its position.
955  *
956  * Returns: the new start of the #GSList
957  *
958  * Since: 2.10
959  */
960 GSList*
g_slist_insert_sorted_with_data(GSList * list,gpointer data,GCompareDataFunc func,gpointer user_data)961 g_slist_insert_sorted_with_data (GSList           *list,
962                                  gpointer          data,
963                                  GCompareDataFunc  func,
964                                  gpointer          user_data)
965 {
966   return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data);
967 }
968 
969 static GSList *
g_slist_sort_merge(GSList * l1,GSList * l2,GFunc compare_func,gpointer user_data)970 g_slist_sort_merge (GSList   *l1,
971                     GSList   *l2,
972                     GFunc     compare_func,
973                     gpointer  user_data)
974 {
975   GSList list, *l;
976   gint cmp;
977 
978   l=&list;
979 
980   while (l1 && l2)
981     {
982       cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
983 
984       if (cmp <= 0)
985         {
986           l=l->next=l1;
987           l1=l1->next;
988         }
989       else
990         {
991           l=l->next=l2;
992           l2=l2->next;
993         }
994     }
995   l->next= l1 ? l1 : l2;
996 
997   return list.next;
998 }
999 
1000 static GSList *
g_slist_sort_real(GSList * list,GFunc compare_func,gpointer user_data)1001 g_slist_sort_real (GSList   *list,
1002                    GFunc     compare_func,
1003                    gpointer  user_data)
1004 {
1005   GSList *l1, *l2;
1006 
1007   if (!list)
1008     return NULL;
1009   if (!list->next)
1010     return list;
1011 
1012   l1 = list;
1013   l2 = list->next;
1014 
1015   while ((l2 = l2->next) != NULL)
1016     {
1017       if ((l2 = l2->next) == NULL)
1018         break;
1019       l1=l1->next;
1020     }
1021   l2 = l1->next;
1022   l1->next = NULL;
1023 
1024   return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data),
1025                              g_slist_sort_real (l2, compare_func, user_data),
1026                              compare_func,
1027                              user_data);
1028 }
1029 
1030 /**
1031  * g_slist_sort:
1032  * @list: a #GSList
1033  * @compare_func: the comparison function used to sort the #GSList.
1034  *     This function is passed the data from 2 elements of the #GSList
1035  *     and should return 0 if they are equal, a negative value if the
1036  *     first element comes before the second, or a positive value if
1037  *     the first element comes after the second.
1038  *
1039  * Sorts a #GSList using the given comparison function. The algorithm
1040  * used is a stable sort.
1041  *
1042  * Returns: the start of the sorted #GSList
1043  */
1044 GSList *
g_slist_sort(GSList * list,GCompareFunc compare_func)1045 g_slist_sort (GSList       *list,
1046               GCompareFunc  compare_func)
1047 {
1048   return g_slist_sort_real (list, (GFunc) compare_func, NULL);
1049 }
1050 
1051 /**
1052  * g_slist_sort_with_data:
1053  * @list: a #GSList
1054  * @compare_func: comparison function
1055  * @user_data: data to pass to comparison function
1056  *
1057  * Like g_slist_sort(), but the sort function accepts a user data argument.
1058  *
1059  * Returns: new head of the list
1060  */
1061 GSList *
g_slist_sort_with_data(GSList * list,GCompareDataFunc compare_func,gpointer user_data)1062 g_slist_sort_with_data (GSList           *list,
1063                         GCompareDataFunc  compare_func,
1064                         gpointer          user_data)
1065 {
1066   return g_slist_sort_real (list, (GFunc) compare_func, user_data);
1067 }
1068