[kdbus] sync with kdbus (kdbus.h - commit: 5ae1ecac44cb)
[platform/upstream/glib.git] / glib / glist.c
index b607abd..18e25da 100644 (file)
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
  * file for a list of people on the GLib Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */
 
-/* 
+/*
  * MT safe
  */
 
 #include "config.h"
 
-#include "glib.h"
-#include "galias.h"
+#include "glist.h"
+#include "gslice.h"
+#include "gmessages.h"
+
+#include "gtestutils.h"
+
+/**
+ * SECTION:linked_lists_double
+ * @title: Doubly-Linked Lists
+ * @short_description: linked lists that can be iterated over in both directions
+ *
+ * The #GList structure and its associated functions provide a standard
+ * doubly-linked list data structure.
+ *
+ * Each element in the list contains a piece of data, together with
+ * pointers which link to the previous and next elements in the list.
+ * Using these pointers it is possible to move through the list in both
+ * directions (unlike the singly-linked [GSList][glib-Singly-Linked-Lists],
+ * which only allows movement through the list in the forward direction).
+ *
+ * The double linked list does not keep track of the number of items 
+ * and does not keep track of both the start and end of the list. If
+ * you want fast access to both the start and the end of the list, 
+ * and/or the number of items in the list, use a
+ * [GQueue][glib-Double-ended-Queues] instead.
+ *
+ * The data contained in each element can be either integer values, by
+ * using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
+ * or simply pointers to any type of data.
+ *
+ * List elements are allocated from the [slice allocator][glib-Memory-Slices],
+ * which is more efficient than allocating elements individually.
+ *
+ * Note that most of the #GList functions expect to be passed a pointer
+ * to the first element in the list. The functions which insert
+ * elements return the new start of the list, which may have changed.
+ *
+ * There is no function to create a #GList. %NULL is considered to be
+ * a valid, empty list so you simply set a #GList* to %NULL to initialize
+ * it.
+ *
+ * To add elements, use g_list_append(), g_list_prepend(),
+ * g_list_insert() and g_list_insert_sorted().
+ *
+ * To visit all elements in the list, use a loop over the list:
+ * |[<!-- language="C" -->
+ * GList *l;
+ * for (l = list; l != NULL; l = l->next)
+ *   {
+ *     // do something with l->data
+ *   }
+ * ]|
+ *
+ * To call a function for each element in the list, use g_list_foreach().
+ *
+ * To loop over the list and modify it (e.g. remove a certain element)
+ * a while loop is more appropriate, for example:
+ * |[<!-- language="C" -->
+ * GList *l = list;
+ * while (l != NULL)
+ *   {
+ *     GList *next = l->next;
+ *     if (should_be_removed (l))
+ *       {
+ *         // possibly free l->data
+ *         list = g_list_delete_link (list, l);
+ *       }
+ *     l = next;
+ *   }
+ * ]|
+ *
+ * To remove elements, use g_list_remove().
+ *
+ * To navigate in a list, use g_list_first(), g_list_last(),
+ * g_list_next(), g_list_previous().
+ *
+ * To find elements in the list use g_list_nth(), g_list_nth_data(),
+ * g_list_find() and g_list_find_custom().
+ *
+ * To find the index of an element use g_list_position() and
+ * g_list_index().
+ *
+ * To free the entire list, use g_list_free() or g_list_free_full().
+ */
+
+/**
+ * GList:
+ * @data: holds the element's data, which can be a pointer to any kind
+ *        of data, or any integer value using the 
+ *        [Type Conversion Macros][glib-Type-Conversion-Macros]
+ * @next: contains the link to the next element in the list
+ * @prev: contains the link to the previous element in the list
+ *
+ * The #GList struct is used for each element in a doubly-linked list.
+ **/
 
+/**
+ * g_list_previous:
+ * @list: an element in a #GList
+ *
+ * A convenience macro to get the previous element in a #GList.
+ * Note that it is considered perfectly acceptable to access
+ * @list->previous directly.
+ *
+ * Returns: the previous element, or %NULL if there are no previous
+ *          elements
+ **/
 
-void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ }
-void g_list_pop_allocator  (void)           { /* present for binary compat only */ }
+/**
+ * g_list_next:
+ * @list: an element in a #GList
+ *
+ * A convenience macro to get the next element in a #GList.
+ * Note that it is considered perfectly acceptable to access
+ * @list->next directly.
+ *
+ * Returns: the next element, or %NULL if there are no more elements
+ **/
 
 #define _g_list_alloc()         g_slice_new (GList)
 #define _g_list_alloc0()        g_slice_new0 (GList)
 #define _g_list_free1(list)     g_slice_free (GList, list)
 
-GList*
+/**
+ * g_list_alloc:
+ *
+ * Allocates space for one #GList element. It is called by
+ * g_list_append(), g_list_prepend(), g_list_insert() and
+ * g_list_insert_sorted() and so is rarely used on its own.
+ *
+ * Returns: a pointer to the newly-allocated #GList element
+ **/
+GList *
 g_list_alloc (void)
 {
   return _g_list_alloc0 ();
@@ -54,10 +173,8 @@ g_list_alloc (void)
  * Frees all of the memory used by a #GList.
  * The freed elements are returned to the slice allocator.
  *
- * <note><para>
- * If list elements contain dynamically-allocated memory, 
- * they should be freed first.
- * </para></note>
+ * If list elements contain dynamically-allocated memory, you should
+ * either use g_list_free_full() or free them manually first.
  */
 void
 g_list_free (GList *list)
@@ -72,6 +189,11 @@ g_list_free (GList *list)
  * Frees one #GList element.
  * It is usually used after g_list_remove_link().
  */
+/**
+ * g_list_free1:
+ *
+ * Another name for g_list_free_1().
+ **/
 void
 g_list_free_1 (GList *list)
 {
@@ -79,42 +201,56 @@ g_list_free_1 (GList *list)
 }
 
 /**
+ * g_list_free_full:
+ * @list: a pointer to a #GList
+ * @free_func: the function to be called to free each element's data
+ *
+ * Convenience method, which frees all the memory used by a #GList,
+ * and calls @free_func on every element's data.
+ *
+ * Since: 2.28
+ */
+void
+g_list_free_full (GList          *list,
+                  GDestroyNotify  free_func)
+{
+  g_list_foreach (list, (GFunc) free_func, NULL);
+  g_list_free (list);
+}
+
+/**
  * g_list_append:
  * @list: a pointer to a #GList
  * @data: the data for the new element
  *
  * Adds a new element on to the end of the list.
  *
- * <note><para>
- * The return value is the new start of the list, which 
- * may have changed, so make sure you store the new value.
- * </para></note>
- *
- * <note><para>
- * Note that g_list_append() has to traverse the entire list 
- * to find the end, which is inefficient when adding multiple 
- * elements. A common idiom to avoid the inefficiency is to prepend 
- * the elements and reverse the list when all elements have been added.
- * </para></note>
- *
- * |[
- * /&ast; Notice that these are initialized to the empty list. &ast;/
- * GList *list = NULL, *number_list = NULL;
- *
- * /&ast; This is a list of strings. &ast;/
- * list = g_list_append (list, "first");
- * list = g_list_append (list, "second");
+ * Note that the return value is the new start of the list,
+ * if @list was empty; make sure you store the new value.
+ *
+ * g_list_append() has to traverse the entire list to find the end,
+ * which is inefficient when adding multiple elements. A common idiom
+ * to avoid the inefficiency is to use g_list_prepend() and reverse
+ * the list with g_list_reverse() when all elements have been added.
+ *
+ * |[<!-- language="C" -->
+ * // Notice that these are initialized to the empty list.
+ * GList *string_list = NULL, *number_list = NULL;
+ *
+ * // This is a list of strings.
+ * string_list = g_list_append (string_list, "first");
+ * string_list = g_list_append (string_list, "second");
  * 
- * /&ast; This is a list of integers. &ast;/
+ * // This is a list of integers.
  * number_list = g_list_append (number_list, GINT_TO_POINTER (27));
  * number_list = g_list_append (number_list, GINT_TO_POINTER (14));
  * ]|
  *
- * Returns: the new start of the #GList
+ * Returns: either @list or the new start of the #GList if @list was %NULL
  */
-GList*
-g_list_append (GList   *list,
-              gpointer  data)
+GList *
+g_list_append (GList    *list,
+               gpointer  data)
 {
   GList *new_list;
   GList *last;
@@ -141,28 +277,31 @@ g_list_append (GList      *list,
 
 /**
  * g_list_prepend:
- * @list: a pointer to a #GList
+ * @list: a pointer to a #GList, this must point to the top of the list
  * @data: the data for the new element
  *
- * Adds a new element on to the start of the list.
+ * Prepends a new element on to the start of the list.
  *
- * <note><para>
- * The return value is the new start of the list, which 
- * may have changed, so make sure you store the new value.
- * </para></note>
+ * Note that the return value is the new start of the list,
+ * which will have changed, so make sure you store the new value. 
  *
- * |[ 
- * /&ast; Notice that it is initialized to the empty list. &ast;/
+ * |[<!-- language="C" -->
+ * // Notice that it is initialized to the empty list.
  * GList *list = NULL;
+ *
  * list = g_list_prepend (list, "last");
  * list = g_list_prepend (list, "first");
  * ]|
  *
- * Returns: the new start of the #GList
+ * Do not use this function to prepend a new element to a different
+ * element than the start of the list. Use g_list_insert_before() instead.
+ *
+ * Returns: a pointer to the newly prepended element, which is the new 
+ *     start of the #GList
  */
-GList*
-g_list_prepend (GList   *list,
-               gpointer  data)
+GList *
+g_list_prepend (GList    *list,
+                gpointer  data)
 {
   GList *new_list;
   
@@ -174,7 +313,7 @@ g_list_prepend (GList        *list,
     {
       new_list->prev = list->prev;
       if (list->prev)
-       list->prev->next = new_list;
+        list->prev->next = new_list;
       list->prev = new_list;
     }
   else
@@ -185,7 +324,7 @@ g_list_prepend (GList        *list,
 
 /**
  * g_list_insert:
- * @list: a pointer to a #GList
+ * @list: a pointer to a #GList, this must point to the top of the list
  * @data: the data for the new element
  * @position: the position to insert the element. If this is 
  *     negative, or is larger than the number of elements in the 
@@ -193,54 +332,50 @@ g_list_prepend (GList      *list,
  * 
  * Inserts a new element into the list at the given position.
  *
- * Returns: the new start of the #GList
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
-g_list_insert (GList   *list,
-              gpointer  data,
-              gint      position)
+GList *
+g_list_insert (GList    *list,
+               gpointer  data,
+               gint      position)
 {
   GList *new_list;
   GList *tmp_list;
-  
+
   if (position < 0)
     return g_list_append (list, data);
   else if (position == 0)
     return g_list_prepend (list, data);
-  
+
   tmp_list = g_list_nth (list, position);
   if (!tmp_list)
     return g_list_append (list, data);
-  
+
   new_list = _g_list_alloc ();
   new_list->data = data;
   new_list->prev = tmp_list->prev;
-  if (tmp_list->prev)
-    tmp_list->prev->next = new_list;
+  tmp_list->prev->next = new_list;
   new_list->next = tmp_list;
   tmp_list->prev = new_list;
-  
-  if (tmp_list == list)
-    return new_list;
-  else
-    return list;
+
+  return list;
 }
 
 /**
  * g_list_insert_before:
- * @list: a pointer to a #GList
+ * @list: a pointer to a #GList, this must point to the top of the list
  * @sibling: the list element before which the new element 
  *     is inserted or %NULL to insert at the end of the list
  * @data: the data for the new element
  *
  * Inserts a new element into the list before the given position.
  *
- * Returns: the new start of the #GList
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
-g_list_insert_before (GList   *list,
-                     GList   *sibling,
-                     gpointer data)
+GList *
+g_list_insert_before (GList    *list,
+                      GList    *sibling,
+                      gpointer  data)
 {
   if (!list)
     {
@@ -259,15 +394,15 @@ g_list_insert_before (GList   *list,
       node->next = sibling;
       sibling->prev = node;
       if (node->prev)
-       {
-         node->prev->next = node;
-         return list;
-       }
+        {
+          node->prev->next = node;
+          return list;
+        }
       else
-       {
-         g_return_val_if_fail (sibling == list, node);
-         return node;
-       }
+        {
+          g_return_val_if_fail (sibling == list, node);
+          return node;
+        }
     }
   else
     {
@@ -275,7 +410,7 @@ g_list_insert_before (GList   *list,
 
       last = list;
       while (last->next)
-       last = last->next;
+        last = last->next;
 
       last->next = _g_list_alloc ();
       last->next->data = data;
@@ -288,17 +423,26 @@ g_list_insert_before (GList   *list,
 
 /**
  * g_list_concat:
- * @list1: a #GList
- * @list2: the #GList to add to the end of the first #GList
+ * @list1: a #GList, this must point to the top of the list
+ * @list2: the #GList to add to the end of the first #GList,
+ *     this must point  to the top of the list
  *
  * Adds the second #GList onto the end of the first #GList.
  * Note that the elements of the second #GList are not copied.
  * They are used directly.
  *
- * Returns: the start of the new #GList
+ * This function is for example used to move an element in the list.
+ * The following example moves an element to the top of the list:
+ * |[<!-- language="C" -->
+ * list = g_list_remove_link (list, llink);
+ * list = g_list_concat (llink, list);
+ * ]|
+ *
+ * Returns: the start of the new #GList, which equals @list1 if not %NULL 
  */
 GList *
-g_list_concat (GList *list1, GList *list2)
+g_list_concat (GList *list1,
+               GList *list2)
 {
   GList *tmp_list;
   
@@ -306,148 +450,160 @@ g_list_concat (GList *list1, GList *list2)
     {
       tmp_list = g_list_last (list1);
       if (tmp_list)
-       tmp_list->next = list2;
+        tmp_list->next = list2;
       else
-       list1 = list2;
+        list1 = list2;
       list2->prev = tmp_list;
     }
   
   return list1;
 }
 
+static inline GList *
+_g_list_remove_link (GList *list,
+                     GList *link)
+{
+  if (link == NULL)
+    return list;
+
+  if (link->prev)
+    {
+      if (link->prev->next == link)
+        link->prev->next = link->next;
+      else
+        g_warning ("corrupted double-linked list detected");
+    }
+  if (link->next)
+    {
+      if (link->next->prev == link)
+        link->next->prev = link->prev;
+      else
+        g_warning ("corrupted double-linked list detected");
+    }
+
+  if (link == list)
+    list = list->next;
+
+  link->next = NULL;
+  link->prev = NULL;
+
+  return list;
+}
+
 /**
  * g_list_remove:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @data: the data of the element to remove
  *
  * Removes an element from a #GList.
  * If two elements contain the same data, only the first is removed.
  * If none of the elements contain the data, the #GList is unchanged.
  *
- * Returns: the new start of the #GList
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
-g_list_remove (GList        *list,
-              gconstpointer  data)
+GList *
+g_list_remove (GList         *list,
+               gconstpointer  data)
 {
   GList *tmp;
-  
+
   tmp = list;
   while (tmp)
     {
       if (tmp->data != data)
-       tmp = tmp->next;
+        tmp = tmp->next;
       else
-       {
-         if (tmp->prev)
-           tmp->prev->next = tmp->next;
-         if (tmp->next)
-           tmp->next->prev = tmp->prev;
-         
-         if (list == tmp)
-           list = list->next;
-         
-         _g_list_free1 (tmp);
-         
-         break;
-       }
+        {
+          list = _g_list_remove_link (list, tmp);
+          _g_list_free1 (tmp);
+
+          break;
+        }
     }
   return list;
 }
 
 /**
  * g_list_remove_all:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @data: data to remove
  *
- * Removes all list nodes with data equal to @data. 
- * Returns the new head of the list. Contrast with 
- * g_list_remove() which removes only the first node 
+ * Removes all list nodes with data equal to @data.
+ * Returns the new head of the list. Contrast with
+ * g_list_remove() which removes only the first node
  * matching the given data.
  *
- * Returns: new head of @list
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
-g_list_remove_all (GList       *list,
-                  gconstpointer data)
+GList *
+g_list_remove_all (GList         *list,
+                   gconstpointer  data)
 {
   GList *tmp = list;
 
   while (tmp)
     {
       if (tmp->data != data)
-       tmp = tmp->next;
+        tmp = tmp->next;
       else
-       {
-         GList *next = tmp->next;
-
-         if (tmp->prev)
-           tmp->prev->next = next;
-         else
-           list = next;
-         if (next)
-           next->prev = tmp->prev;
-
-         _g_list_free1 (tmp);
-         tmp = next;
-       }
-    }
-  return list;
-}
+        {
+          GList *next = tmp->next;
 
-static inline GList*
-_g_list_remove_link (GList *list,
-                    GList *link)
-{
-  if (link)
-    {
-      if (link->prev)
-       link->prev->next = link->next;
-      if (link->next)
-       link->next->prev = link->prev;
-      
-      if (link == list)
-       list = list->next;
-      
-      link->next = NULL;
-      link->prev = NULL;
+          if (tmp->prev)
+            tmp->prev->next = next;
+          else
+            list = next;
+          if (next)
+            next->prev = tmp->prev;
+
+          _g_list_free1 (tmp);
+          tmp = next;
+        }
     }
-  
   return list;
 }
 
 /**
  * g_list_remove_link:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @llink: an element in the #GList
  *
  * Removes an element from a #GList, without freeing the element.
  * The removed element's prev and next links are set to %NULL, so 
  * that it becomes a self-contained list with one element.
  *
- * Returns: the new start of the #GList, without the element
+ * This function is for example used to move an element in the list
+ * (see the example for g_list_concat()) or to remove an element in
+ * the list before freeing its data:
+ * |[<!-- language="C" --> 
+ * list = g_list_remove_link (list, llink);
+ * free_some_data_that_may_access_the_list_again (llink->data);
+ * g_list_free (llink);
+ * ]|
+ *
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
+GList *
 g_list_remove_link (GList *list,
-                   GList *llink)
+                    GList *llink)
 {
   return _g_list_remove_link (list, llink);
 }
 
 /**
  * g_list_delete_link:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @link_: node to delete from @list
  *
  * Removes the node link_ from the list and frees it. 
  * Compare this to g_list_remove_link() which removes the node 
  * without freeing it.
  *
- * Returns: the new head of @list
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
+GList *
 g_list_delete_link (GList *list,
-                   GList *link_)
+                    GList *link_)
 {
   list = _g_list_remove_link (list, link_);
   _g_list_free1 (link_);
@@ -457,21 +613,59 @@ g_list_delete_link (GList *list,
 
 /**
  * g_list_copy:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  *
  * Copies a #GList.
  *
- * <note><para>
  * Note that this is a "shallow" copy. If the list elements 
  * consist of pointers to data, the pointers are copied but 
- * the actual data is not.
- * </para></note>
+ * the actual data is not. See g_list_copy_deep() if you need
+ * to copy the data as well.
  *
- * Returns: a copy of @list
+ * Returns: the start of the new list that holds the same data as @list
  */
-GList*
+GList *
 g_list_copy (GList *list)
 {
+  return g_list_copy_deep (list, NULL, NULL);
+}
+
+/**
+ * g_list_copy_deep:
+ * @list: a #GList, this must point to the top of the list
+ * @func: a copy function used to copy every element in the list
+ * @user_data: user data passed to the copy function @func, or %NULL
+ *
+ * Makes a full (deep) copy of a #GList.
+ *
+ * In contrast with g_list_copy(), this function uses @func to make
+ * a copy of each list element, in addition to copying the list
+ * container itself.
+ *
+ * @func, as a #GCopyFunc, takes two arguments, the data to be copied
+ * and a @user_data pointer. It's safe to pass %NULL as user_data,
+ * if the copy function takes only one argument.
+ *
+ * For instance, if @list holds a list of GObjects, you can do:
+ * |[<!-- language="C" -->   
+ * another_list = g_list_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
+ * ]|
+ *
+ * And, to entirely free the new list, you could do:
+ * |[<!-- language="C" --> 
+ * g_list_free_full (another_list, g_object_unref);
+ * ]|
+ *
+ * Returns: the start of the new list that holds a full copy of @list, 
+ *     use g_list_free_full() to free it
+ *
+ * Since: 2.34
+ */
+GList *
+g_list_copy_deep (GList     *list,
+                  GCopyFunc  func,
+                  gpointer   user_data)
+{
   GList *new_list = NULL;
 
   if (list)
@@ -479,18 +673,24 @@ g_list_copy (GList *list)
       GList *last;
 
       new_list = _g_list_alloc ();
-      new_list->data = list->data;
+      if (func)
+        new_list->data = func (list->data, user_data);
+      else
+        new_list->data = list->data;
       new_list->prev = NULL;
       last = new_list;
       list = list->next;
       while (list)
-       {
-         last->next = _g_list_alloc ();
-         last->next->prev = last;
-         last = last->next;
-         last->data = list->data;
-         list = list->next;
-       }
+        {
+          last->next = _g_list_alloc ();
+          last->next->prev = last;
+          last = last->next;
+          if (func)
+            last->data = func (list->data, user_data);
+          else
+            last->data = list->data;
+          list = list->next;
+        }
       last->next = NULL;
     }
 
@@ -499,14 +699,14 @@ g_list_copy (GList *list)
 
 /**
  * g_list_reverse:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  *
  * Reverses a #GList.
  * It simply switches the next and prev pointers of each element.
  *
  * Returns: the start of the reversed #GList
  */
-GList*
+GList *
 g_list_reverse (GList *list)
 {
   GList *last;
@@ -525,7 +725,7 @@ g_list_reverse (GList *list)
 
 /**
  * g_list_nth:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @n: the position of the element, counting from 0
  *
  * Gets the element at the given position in a #GList.
@@ -533,9 +733,9 @@ g_list_reverse (GList *list)
  * Returns: the element, or %NULL if the position is off 
  *     the end of the #GList
  */
-GList*
+GList *
 g_list_nth (GList *list,
-           guint  n)
+            guint  n)
 {
   while ((n-- > 0) && list)
     list = list->next;
@@ -553,9 +753,9 @@ g_list_nth (GList *list,
  * Returns: the element, or %NULL if the position is 
  *     off the end of the #GList
  */
-GList*
+GList *
 g_list_nth_prev (GList *list,
-                guint  n)
+                 guint  n)
 {
   while ((n-- > 0) && list)
     list = list->prev;
@@ -565,7 +765,7 @@ g_list_nth_prev (GList *list,
 
 /**
  * g_list_nth_data:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @n: the position of the element
  *
  * Gets the data of the element at the given position.
@@ -574,8 +774,8 @@ g_list_nth_prev (GList *list,
  *     is off the end of the #GList
  */
 gpointer
-g_list_nth_data (GList     *list,
-                guint      n)
+g_list_nth_data (GList *list,
+                 guint  n)
 {
   while ((n-- > 0) && list)
     list = list->next;
@@ -585,23 +785,21 @@ g_list_nth_data (GList     *list,
 
 /**
  * g_list_find:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @data: the element data to find
  *
- * Finds the element in a #GList which 
- * contains the given data.
+ * Finds the element in a #GList which contains the given data.
  *
- * Returns: the found #GList element, 
- *     or %NULL if it is not found
+ * Returns: the found #GList element, or %NULL if it is not found
  */
-GList*
+GList *
 g_list_find (GList         *list,
-            gconstpointer  data)
+             gconstpointer  data)
 {
   while (list)
     {
       if (list->data == data)
-       break;
+        break;
       list = list->next;
     }
   
@@ -610,7 +808,7 @@ g_list_find (GList         *list,
 
 /**
  * g_list_find_custom:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @data: user data passed to the function
  * @func: the function to call for each element. 
  *     It should return 0 when the desired element is found
@@ -624,27 +822,26 @@ g_list_find (GList         *list,
  *
  * Returns: the found #GList element, or %NULL if it is not found
  */
-GList*
+GList *
 g_list_find_custom (GList         *list,
-                   gconstpointer  data,
-                   GCompareFunc   func)
+                    gconstpointer  data,
+                    GCompareFunc   func)
 {
   g_return_val_if_fail (func != NULL, list);
 
   while (list)
     {
       if (! func (list->data, data))
-       return list;
+        return list;
       list = list->next;
     }
 
   return NULL;
 }
 
-
 /**
  * g_list_position:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @llink: an element in the #GList
  *
  * Gets the position of the given element 
@@ -655,7 +852,7 @@ g_list_find_custom (GList         *list,
  */
 gint
 g_list_position (GList *list,
-                GList *llink)
+                 GList *llink)
 {
   gint i;
 
@@ -663,7 +860,7 @@ g_list_position (GList *list,
   while (list)
     {
       if (list == llink)
-       return i;
+        return i;
       i++;
       list = list->next;
     }
@@ -673,7 +870,7 @@ g_list_position (GList *list,
 
 /**
  * g_list_index:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @data: the data to find
  *
  * Gets the position of the element containing 
@@ -684,7 +881,7 @@ g_list_position (GList *list,
  */
 gint
 g_list_index (GList         *list,
-             gconstpointer  data)
+              gconstpointer  data)
 {
   gint i;
 
@@ -692,7 +889,7 @@ g_list_index (GList         *list,
   while (list)
     {
       if (list->data == data)
-       return i;
+        return i;
       i++;
       list = list->next;
     }
@@ -702,20 +899,20 @@ g_list_index (GList         *list,
 
 /**
  * g_list_last:
- * @list: a #GList
+ * @list: any #GList element
  *
  * Gets the last element in a #GList.
  *
- * Returns: the last element in the #GList, 
+ * Returns: the last element in the #GList,
  *     or %NULL if the #GList has no elements
  */
-GList*
+GList *
 g_list_last (GList *list)
 {
   if (list)
     {
       while (list->next)
-       list = list->next;
+        list = list->next;
     }
   
   return list;
@@ -723,20 +920,20 @@ g_list_last (GList *list)
 
 /**
  * g_list_first:
- * @list: a #GList
+ * @list: any #GList element
  *
  * Gets the first element in a #GList.
  *
  * Returns: the first element in the #GList, 
  *     or %NULL if the #GList has no elements
  */
-GList*
+GList *
 g_list_first (GList *list)
 {
   if (list)
     {
       while (list->prev)
-       list = list->prev;
+        list = list->prev;
     }
   
   return list;
@@ -744,14 +941,13 @@ g_list_first (GList *list)
 
 /**
  * g_list_length:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  *
  * Gets the number of elements in a #GList.
  *
- * <note><para>
- * This function iterates over the whole list to 
- * count its elements.
- * </para></note>
+ * This function iterates over the whole list to count its elements.
+ * Use a #GQueue instead of a GList if you regularly need the number
+ * of items. 
  *
  * Returns: the number of elements in the #GList
  */
@@ -772,16 +968,24 @@ g_list_length (GList *list)
 
 /**
  * g_list_foreach:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @func: the function to call with each element's data
  * @user_data: user data to pass to the function
  *
  * Calls a function for each element of a #GList.
  */
+/**
+ * GFunc:
+ * @data: the element's data
+ * @user_data: user data passed to g_list_foreach() or g_slist_foreach()
+ *
+ * Specifies the type of functions passed to g_list_foreach() and
+ * g_slist_foreach().
+ */
 void
-g_list_foreach (GList   *list,
-               GFunc     func,
-               gpointer  user_data)
+g_list_foreach (GList    *list,
+                GFunc     func,
+                gpointer  user_data)
 {
   while (list)
     {
@@ -793,9 +997,9 @@ g_list_foreach (GList        *list,
 
 static GList*
 g_list_insert_sorted_real (GList    *list,
-                          gpointer  data,
-                          GFunc     func,
-                          gpointer  user_data)
+                           gpointer  data,
+                           GFunc     func,
+                           gpointer  user_data)
 {
   GList *tmp_list = list;
   GList *new_list;
@@ -845,7 +1049,8 @@ g_list_insert_sorted_real (GList    *list,
 
 /**
  * g_list_insert_sorted:
- * @list: a pointer to a #GList
+ * @list: a pointer to a #GList, this must point to the top of the
+ *     already sorted list
  * @data: the data for the new element
  * @func: the function to compare elements in the list. It should 
  *     return a number > 0 if the first parameter comes after the 
@@ -854,46 +1059,57 @@ g_list_insert_sorted_real (GList    *list,
  * Inserts a new element into the list, using the given comparison 
  * function to determine its position.
  *
- * Returns: the new start of the #GList
+ * If you are adding many new elements to a list, and the number of
+ * new elements is much larger than the length of the list, use
+ * g_list_prepend() to add the new items and sort the list afterwards
+ * with g_list_sort().
+ *
+ * Returns: the (possibly changed) start of the #GList
  */
-GList*
+GList *
 g_list_insert_sorted (GList        *list,
-                     gpointer      data,
-                     GCompareFunc  func)
+                      gpointer      data,
+                      GCompareFunc  func)
 {
   return g_list_insert_sorted_real (list, data, (GFunc) func, NULL);
 }
 
 /**
  * g_list_insert_sorted_with_data:
- * @list: a pointer to a #GList
+ * @list: a pointer to a #GList, this must point to the top of the
+ *     already sorted list
  * @data: the data for the new element
- * @func: the function to compare elements in the list. 
- *     It should return a number > 0 if the first parameter 
- *     comes after the second parameter in the sort order.
- * @user_data: user data to pass to comparison function.
+ * @func: the function to compare elements in the list. It should
+ *     return a number > 0 if the first parameter  comes after the
+ *     second parameter in the sort order.
+ * @user_data: user data to pass to comparison function
  *
  * Inserts a new element into the list, using the given comparison 
  * function to determine its position.
  *
- * Returns: the new start of the #GList
+ * If you are adding many new elements to a list, and the number of
+ * new elements is much larger than the length of the list, use
+ * g_list_prepend() to add the new items and sort the list afterwards
+ * with g_list_sort().
+ *
+ * Returns: the (possibly changed) start of the #GList
  *
  * Since: 2.10
  */
-GList*
+GList *
 g_list_insert_sorted_with_data (GList            *list,
-                               gpointer          data,
-                               GCompareDataFunc  func,
-                               gpointer          user_data)
+                                gpointer          data,
+                                GCompareDataFunc  func,
+                                gpointer          user_data)
 {
   return g_list_insert_sorted_real (list, data, (GFunc) func, user_data);
 }
 
 static GList *
 g_list_sort_merge (GList     *l1, 
-                  GList     *l2,
-                  GFunc     compare_func,
-                  gpointer  user_data)
+                   GList     *l2,
+                   GFunc     compare_func,
+                   gpointer  user_data)
 {
   GList list, *l, *lprev;
   gint cmp;
@@ -907,13 +1123,13 @@ g_list_sort_merge (GList     *l1,
 
       if (cmp <= 0)
         {
-         l->next = l1;
-         l1 = l1->next;
+          l->next = l1;
+          l1 = l1->next;
         } 
       else 
-       {
-         l->next = l2;
-         l2 = l2->next;
+        {
+          l->next = l2;
+          l2 = l2->next;
         }
       l = l->next;
       l->prev = lprev; 
@@ -925,10 +1141,10 @@ g_list_sort_merge (GList     *l1,
   return list.next;
 }
 
-static GList* 
+static GList 
 g_list_sort_real (GList    *list,
-                 GFunc     compare_func,
-                 gpointer  user_data)
+                  GFunc     compare_func,
+                  gpointer  user_data)
 {
   GList *l1, *l2;
   
@@ -943,57 +1159,81 @@ g_list_sort_real (GList    *list,
   while ((l2 = l2->next) != NULL)
     {
       if ((l2 = l2->next) == NULL) 
-       break;
+        break;
       l1 = l1->next;
     }
   l2 = l1->next; 
   l1->next = NULL; 
 
   return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data),
-                           g_list_sort_real (l2, compare_func, user_data),
-                           compare_func,
-                           user_data);
+                            g_list_sort_real (l2, compare_func, user_data),
+                            compare_func,
+                            user_data);
 }
 
 /**
  * g_list_sort:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @compare_func: the comparison function used to sort the #GList.
  *     This function is passed the data from 2 elements of the #GList 
  *     and should return 0 if they are equal, a negative value if the 
  *     first element comes before the second, or a positive value if 
  *     the first element comes after the second.
  *
- * Sorts a #GList using the given comparison function.
+ * Sorts a #GList using the given comparison function. The algorithm 
+ * used is a stable sort.
+ *
+ * Returns: the (possibly changed) start of the #GList
+ */
+/**
+ * GCompareFunc:
+ * @a: a value
+ * @b: a value to compare with
+ *
+ * Specifies the type of a comparison function used to compare two
+ * values.  The function should return a negative integer if the first
+ * value comes before the second, 0 if they are equal, or a positive
+ * integer if the first value comes after the second.
  *
- * Returns: the start of the sorted #GList
+ * Returns: negative value if @a < @b; zero if @a = @b; positive
+ *          value if @a > @b
  */
 GList *
 g_list_sort (GList        *list,
-            GCompareFunc  compare_func)
+             GCompareFunc  compare_func)
 {
   return g_list_sort_real (list, (GFunc) compare_func, NULL);
-                           
 }
 
 /**
  * g_list_sort_with_data:
- * @list: a #GList
+ * @list: a #GList, this must point to the top of the list
  * @compare_func: comparison function
  * @user_data: user data to pass to comparison function
  *
  * Like g_list_sort(), but the comparison function accepts 
  * a user data argument.
  *
- * Returns: the new head of @list
+ * Returns: the (possibly changed) start of the #GList
+ */
+/**
+ * GCompareDataFunc:
+ * @a: a value
+ * @b: a value to compare with
+ * @user_data: user data
+ *
+ * Specifies the type of a comparison function used to compare two
+ * values.  The function should return a negative integer if the first
+ * value comes before the second, 0 if they are equal, or a positive
+ * integer if the first value comes after the second.
+ *
+ * Returns: negative value if @a < @b; zero if @a = @b; positive
+ *          value if @a > @b
  */
 GList *
 g_list_sort_with_data (GList            *list,
-                      GCompareDataFunc  compare_func,
-                      gpointer          user_data)
+                       GCompareDataFunc  compare_func,
+                       gpointer          user_data)
 {
   return g_list_sort_real (list, (GFunc) compare_func, user_data);
 }
-
-#define __G_LIST_C__
-#include "galiasdef.c"