Coverage Report

Created: 2025-11-02 06:51

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