1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-list.c Generic linked list utility (internal to D-BUS implementation)
4 * Copyright (C) 2002 Red Hat, Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-internals.h"
25 #include "dbus-list.h"
26 #include "dbus-mempool.h"
27 #include "dbus-threads.h"
30 * @defgroup DBusList Linked list
31 * @ingroup DBusInternals
32 * @brief DBusList data structure
34 * Types and functions related to DBusList.
37 static DBusMemPool *list_pool;
38 _DBUS_DEFINE_GLOBAL_LOCK (list);
41 * @defgroup DBusListInternals Linked list implementation details
42 * @ingroup DBusInternals
43 * @brief DBusList implementation details
45 * The guts of DBusList.
50 /* the mem pool is probably a speed hit, with the thread
51 * lock, though it does still save memory - unknown.
54 alloc_link (void *data)
58 if (!_DBUS_LOCK (list))
61 if (list_pool == NULL)
63 list_pool = _dbus_mem_pool_new (sizeof (DBusList), TRUE);
65 if (list_pool == NULL)
71 link = _dbus_mem_pool_alloc (list_pool);
74 _dbus_mem_pool_free (list_pool);
82 link = _dbus_mem_pool_alloc (list_pool);
94 free_link (DBusList *link)
97 if (_dbus_mem_pool_dealloc (list_pool, link))
99 _dbus_mem_pool_free (list_pool);
107 link_before (DBusList **list,
108 DBusList *before_this_link,
119 link->next = before_this_link;
120 link->prev = before_this_link->prev;
121 before_this_link->prev = link;
122 link->prev->next = link;
124 if (before_this_link == *list)
130 link_after (DBusList **list,
131 DBusList *after_this_link,
142 link->prev = after_this_link;
143 link->next = after_this_link->next;
144 after_this_link->next = link;
145 link->next->prev = link;
152 * @addtogroup DBusList
159 * A node in a linked list.
161 * DBusList is a circular list; that is, the tail of the list
162 * points back to the head of the list. The empty list is
163 * represented by a #NULL pointer.
167 * @def _dbus_list_get_next_link
169 * Gets the next link in the list, or #NULL if
170 * there are no more links. Used for iteration.
174 * link = _dbus_list_get_first_link (&list);
175 * while (link != NULL)
177 * printf ("value is %p\n", link->data);
178 * link = _dbus_list_get_next_link (&link);
182 * @param list address of the list head.
183 * @param link current link.
184 * @returns the next link, or %NULL if none.
189 * @def _dbus_list_get_prev_link
191 * Gets the previous link in the list, or #NULL if
192 * there are no more links. Used for iteration.
196 * link = _dbus_list_get_last_link (&list);
197 * while (link != NULL)
199 * printf ("value is %p\n", link->data);
200 * link = _dbus_list_get_prev_link (&link);
204 * @param list address of the list head.
205 * @param link current link.
206 * @returns the previous link, or %NULL if none.
211 * Allocates a linked list node. Useful for preallocating
212 * nodes and using _dbus_list_append_link() to avoid
215 * @param data the value to store in the link.
216 * @returns a newly allocated link.
219 _dbus_list_alloc_link (void *data)
221 return alloc_link (data);
225 * Frees a linked list node allocated with _dbus_list_alloc_link.
226 * Does not free the data in the node.
228 * @param link the list node
231 _dbus_list_free_link (DBusList *link)
238 * Appends a value to the list. May return #FALSE
239 * if insufficient memory exists to add a list link.
240 * This is a constant-time operation.
242 * @param list address of the list head.
243 * @param data the value to append.
244 * @returns #TRUE on success.
247 _dbus_list_append (DBusList **list,
250 if (!_dbus_list_prepend (list, data))
253 /* Now cycle the list forward one so the prepended node is the tail */
254 *list = (*list)->next;
260 * Prepends a value to the list. May return #FALSE
261 * if insufficient memory exists to add a list link.
262 * This is a constant-time operation.
264 * @param list address of the list head.
265 * @param data the value to prepend.
266 * @returns #TRUE on success.
269 _dbus_list_prepend (DBusList **list,
274 link = alloc_link (data);
278 link_before (list, *list, link);
284 * Appends a link to the list.
285 * Cannot fail due to out of memory.
286 * This is a constant-time operation.
288 * @param list address of the list head.
289 * @param link the link to append.
292 _dbus_list_append_link (DBusList **list,
295 _dbus_list_prepend_link (list, link);
297 /* Now cycle the list forward one so the prepended node is the tail */
298 *list = (*list)->next;
302 * Prepends a link to the list.
303 * Cannot fail due to out of memory.
304 * This is a constant-time operation.
306 * @param list address of the list head.
307 * @param link the link to prepend.
310 _dbus_list_prepend_link (DBusList **list,
313 link_before (list, *list, link);
317 * Inserts data into the list before the given existing link.
319 * @param list the list to modify
320 * @param before_this_link existing link to insert before, or #NULL to append
321 * @param data the value to insert
322 * @returns #TRUE on success, #FALSE if memory allocation fails
325 _dbus_list_insert_before (DBusList **list,
326 DBusList *before_this_link,
331 if (before_this_link == NULL)
332 return _dbus_list_append (list, data);
335 link = alloc_link (data);
339 link_before (list, before_this_link, link);
346 * Inserts data into the list after the given existing link.
348 * @param list the list to modify
349 * @param after_this_link existing link to insert after, or #NULL to prepend
350 * @param data the value to insert
351 * @returns #TRUE on success, #FALSE if memory allocation fails
354 _dbus_list_insert_after (DBusList **list,
355 DBusList *after_this_link,
360 if (after_this_link == NULL)
361 return _dbus_list_prepend (list, data);
364 link = alloc_link (data);
368 link_after (list, after_this_link, link);
375 * Removes a value from the list. Only removes the
376 * first value equal to the given data pointer,
377 * even if multiple values exist which match.
378 * This is a linear-time operation.
380 * @param list address of the list head.
381 * @param data the value to remove.
382 * @returns #TRUE if a value was found to remove.
385 _dbus_list_remove (DBusList **list,
393 if (link->data == data)
395 _dbus_list_remove_link (list, link);
399 link = _dbus_list_get_next_link (list, link);
406 * Removes a value from the list. Only removes the
407 * last value equal to the given data pointer,
408 * even if multiple values exist which match.
409 * This is a linear-time operation.
411 * @param list address of the list head.
412 * @param data the value to remove.
413 * @returns #TRUE if a value was found to remove.
416 _dbus_list_remove_last (DBusList **list,
421 link = _dbus_list_get_last_link (list);
425 if (link->data == data)
427 _dbus_list_remove_link (list, link);
431 link = _dbus_list_get_prev_link (list, link);
438 _dbus_list_unlink (DBusList **list,
441 if (link->next == link)
443 /* one-element list */
448 link->prev->next = link->next;
449 link->next->prev = link->prev;
457 * Removes a link from the list. This is a constant-time operation.
459 * @param list address of the list head.
460 * @param link the list link to remove.
463 _dbus_list_remove_link (DBusList **list,
466 _dbus_list_unlink (list, link);
471 * Frees all links in the list and sets the list head to #NULL. Does
472 * not free the data in each link, for obvious reasons. This is a
473 * linear-time operation.
475 * @param list address of the list head.
478 _dbus_list_clear (DBusList **list)
485 DBusList *next = _dbus_list_get_next_link (list, link);
496 * Gets the first link in the list.
497 * This is a constant-time operation.
499 * @param list address of the list head.
500 * @returns the first link, or #NULL for an empty list.
503 _dbus_list_get_first_link (DBusList **list)
509 * Gets the last link in the list.
510 * This is a constant-time operation.
512 * @param list address of the list head.
513 * @returns the last link, or #NULL for an empty list.
516 _dbus_list_get_last_link (DBusList **list)
521 return (*list)->prev;
525 * Gets the last data in the list.
526 * This is a constant-time operation.
528 * @param list address of the list head.
529 * @returns the last data in the list, or #NULL for an empty list.
532 _dbus_list_get_last (DBusList **list)
537 return (*list)->prev->data;
541 * Gets the first data in the list.
542 * This is a constant-time operation.
544 * @param list address of the list head.
545 * @returns the first data in the list, or #NULL for an empty list.
548 _dbus_list_get_first (DBusList **list)
553 return (*list)->data;
557 * Removes the first link in the list and returns it. This is a
558 * constant-time operation.
560 * @param list address of the list head.
561 * @returns the first link in the list, or #NULL for an empty list.
564 _dbus_list_pop_first_link (DBusList **list)
568 link = _dbus_list_get_first_link (list);
572 _dbus_list_unlink (list, link);
578 * Removes the first value in the list and returns it. This is a
579 * constant-time operation.
581 * @param list address of the list head.
582 * @returns the first data in the list, or #NULL for an empty list.
585 _dbus_list_pop_first (DBusList **list)
590 link = _dbus_list_get_first_link (list);
595 _dbus_list_remove_link (list, link);
601 * Removes the last value in the list and returns it. This is a
602 * constant-time operation.
604 * @param list address of the list head.
605 * @returns the last data in the list, or #NULL for an empty list.
608 _dbus_list_pop_last (DBusList **list)
613 link = _dbus_list_get_last_link (list);
618 _dbus_list_remove_link (list, link);
624 * Removes the last link in the list and returns it. This is a
625 * constant-time operation.
627 * @param list address of the list head.
628 * @returns the last link in the list, or #NULL for an empty list.
631 _dbus_list_pop_last_link (DBusList **list)
635 link = _dbus_list_get_last_link (list);
639 _dbus_list_unlink (list, link);
645 * Copies a list. This is a linear-time operation. If there isn't
646 * enough memory to copy the entire list, the destination list will be
649 * @param list address of the head of the list to copy.
650 * @param dest address where the copied list should be placed.
651 * @returns #TRUE on success, #FALSE if not enough memory.
654 _dbus_list_copy (DBusList **list,
659 _dbus_assert (list != dest);
666 if (!_dbus_list_append (dest, link->data))
668 /* free what we have so far */
669 _dbus_list_clear (dest);
673 link = _dbus_list_get_next_link (list, link);
680 * Gets the length of a list. This is a linear-time
683 * @param list address of the head of the list
684 * @returns number of elements in the list.
687 _dbus_list_get_length (DBusList **list)
699 link = _dbus_list_get_next_link (list, link);
706 * Calls the given function for each element in the list. The
707 * function is passed the list element as its first argument, and the
708 * given data as its second argument.
710 * @param list address of the head of the list.
711 * @param function function to call for each element.
712 * @param data extra data for the function.
716 _dbus_list_foreach (DBusList **list,
717 DBusForeachFunction function,
725 DBusList *next = _dbus_list_get_next_link (list, link);
727 (* function) (link->data, data);
734 * Check whether length is exactly one.
736 * @param list the list
737 * @returns #TRUE if length is exactly one
740 _dbus_list_length_is_one (DBusList **list)
742 return (*list != NULL &&
743 (*list)->next == *list);
748 #ifdef DBUS_BUILD_TESTS
749 #include "dbus-test.h"
753 verify_list (DBusList **list)
763 if (link->next == link)
765 _dbus_assert (link->prev == link);
766 _dbus_assert (*list == link);
774 _dbus_assert (link->prev->next == link);
775 _dbus_assert (link->next->prev == link);
778 while (link != *list);
780 _dbus_assert (length == _dbus_list_get_length (list));
783 _dbus_assert (_dbus_list_length_is_one (list));
785 _dbus_assert (!_dbus_list_length_is_one (list));
789 is_ascending_sequence (DBusList **list)
794 prev = _DBUS_INT_MIN;
796 link = _dbus_list_get_first_link (list);
799 int v = _DBUS_POINTER_TO_INT (link->data);
806 link = _dbus_list_get_next_link (list, link);
813 is_descending_sequence (DBusList **list)
818 prev = _DBUS_INT_MAX;
820 link = _dbus_list_get_first_link (list);
823 int v = _DBUS_POINTER_TO_INT (link->data);
830 link = _dbus_list_get_next_link (list, link);
837 all_even_values (DBusList **list)
841 link = _dbus_list_get_first_link (list);
844 int v = _DBUS_POINTER_TO_INT (link->data);
849 link = _dbus_list_get_next_link (list, link);
856 all_odd_values (DBusList **list)
860 link = _dbus_list_get_first_link (list);
863 int v = _DBUS_POINTER_TO_INT (link->data);
868 link = _dbus_list_get_next_link (list, link);
875 lists_equal (DBusList **list1,
881 link1 = _dbus_list_get_first_link (list1);
882 link2 = _dbus_list_get_first_link (list2);
883 while (link1 && link2)
885 if (link1->data != link2->data)
888 link1 = _dbus_list_get_next_link (list1, link1);
889 link2 = _dbus_list_get_next_link (list2, link2);
899 * @ingroup DBusListInternals
900 * Unit test for DBusList
901 * @returns #TRUE on success.
904 _dbus_list_test (void)
917 /* Test append and prepend */
922 if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)))
923 _dbus_assert_not_reached ("could not allocate for append");
925 if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)))
926 _dbus_assert_not_reached ("count not allocate for prepend");
929 verify_list (&list1);
930 verify_list (&list2);
932 _dbus_assert (_dbus_list_get_length (&list1) == i);
933 _dbus_assert (_dbus_list_get_length (&list2) == i);
936 _dbus_assert (is_ascending_sequence (&list1));
937 _dbus_assert (is_descending_sequence (&list2));
939 /* Test list clear */
940 _dbus_list_clear (&list1);
941 _dbus_list_clear (&list2);
943 verify_list (&list1);
944 verify_list (&list2);
946 /* Test get_first, get_last, pop_first, pop_last */
951 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
952 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
965 got_data1 = _dbus_list_get_last (&list1);
966 got_data2 = _dbus_list_get_first (&list2);
968 data1 = _dbus_list_pop_last (&list1);
969 data2 = _dbus_list_pop_first (&list2);
971 _dbus_assert (got_data1 == data1);
972 _dbus_assert (got_data2 == data2);
974 _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
975 _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
977 verify_list (&list1);
978 verify_list (&list2);
980 _dbus_assert (is_ascending_sequence (&list1));
981 _dbus_assert (is_descending_sequence (&list2));
986 _dbus_assert (list1 == NULL);
987 _dbus_assert (list2 == NULL);
989 /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */
994 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
995 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
1002 DBusList *got_link1;
1003 DBusList *got_link2;
1011 got_link1 = _dbus_list_get_last_link (&list1);
1012 got_link2 = _dbus_list_get_first_link (&list2);
1014 link1 = _dbus_list_pop_last_link (&list1);
1015 link2 = _dbus_list_pop_first_link (&list2);
1017 _dbus_assert (got_link1 == link1);
1018 _dbus_assert (got_link2 == link2);
1020 data1 = link1->data;
1021 data2 = link2->data;
1023 _dbus_list_free_link (link1);
1024 _dbus_list_free_link (link2);
1026 _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
1027 _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
1029 verify_list (&list1);
1030 verify_list (&list2);
1032 _dbus_assert (is_ascending_sequence (&list1));
1033 _dbus_assert (is_descending_sequence (&list2));
1038 _dbus_assert (list1 == NULL);
1039 _dbus_assert (list2 == NULL);
1041 /* Test iteration */
1046 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
1047 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
1050 verify_list (&list1);
1051 verify_list (&list2);
1053 _dbus_assert (_dbus_list_get_length (&list1) == i);
1054 _dbus_assert (_dbus_list_get_length (&list2) == i);
1057 _dbus_assert (is_ascending_sequence (&list1));
1058 _dbus_assert (is_descending_sequence (&list2));
1061 link2 = _dbus_list_get_first_link (&list2);
1062 while (link2 != NULL)
1064 verify_list (&link2); /* pretend this link is the head */
1066 _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
1068 link2 = _dbus_list_get_next_link (&list2, link2);
1073 link1 = _dbus_list_get_first_link (&list1);
1074 while (link1 != NULL)
1076 verify_list (&link1); /* pretend this link is the head */
1078 _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1080 link1 = _dbus_list_get_next_link (&list1, link1);
1085 link1 = _dbus_list_get_last_link (&list1);
1086 while (link1 != NULL)
1088 verify_list (&link1); /* pretend this link is the head */
1090 _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1092 link1 = _dbus_list_get_prev_link (&list1, link1);
1096 _dbus_list_clear (&list1);
1097 _dbus_list_clear (&list2);
1104 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
1105 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
1114 if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
1115 _dbus_assert_not_reached ("element should have been in list");
1116 if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
1117 _dbus_assert_not_reached ("element should have been in list");
1119 verify_list (&list1);
1120 verify_list (&list2);
1125 _dbus_assert (all_odd_values (&list1));
1126 _dbus_assert (all_odd_values (&list2));
1128 _dbus_list_clear (&list1);
1129 _dbus_list_clear (&list2);
1131 /* test removing the other half of the elements */
1136 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
1137 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
1146 if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
1147 _dbus_assert_not_reached ("element should have been in list");
1148 if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
1149 _dbus_assert_not_reached ("element should have been in list");
1151 verify_list (&list1);
1152 verify_list (&list2);
1157 _dbus_assert (all_even_values (&list1));
1158 _dbus_assert (all_even_values (&list2));
1160 /* clear list using remove_link */
1161 while (list1 != NULL)
1163 _dbus_list_remove_link (&list1, list1);
1164 verify_list (&list1);
1166 while (list2 != NULL)
1168 _dbus_list_remove_link (&list2, list2);
1169 verify_list (&list2);
1172 /* Test remove link more generally */
1176 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
1177 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
1182 link2 = _dbus_list_get_first_link (&list2);
1183 while (link2 != NULL)
1185 DBusList *next = _dbus_list_get_next_link (&list2, link2);
1187 _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
1190 _dbus_list_remove_link (&list2, link2);
1192 verify_list (&list2);
1198 _dbus_assert (all_odd_values (&list2));
1199 _dbus_list_clear (&list2);
1202 link1 = _dbus_list_get_first_link (&list1);
1203 while (link1 != NULL)
1205 DBusList *next = _dbus_list_get_next_link (&list1, link1);
1207 _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1210 _dbus_list_remove_link (&list1, link1);
1212 verify_list (&list1);
1218 _dbus_assert (all_even_values (&list1));
1219 _dbus_list_clear (&list1);
1221 /* Test copying a list */
1225 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
1226 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
1230 /* bad pointers, because they are allowed in the copy dest */
1231 copy1 = _DBUS_INT_TO_POINTER (0x342234);
1232 copy2 = _DBUS_INT_TO_POINTER (23);
1234 _dbus_list_copy (&list1, ©1);
1235 verify_list (&list1);
1236 verify_list (©1);
1237 _dbus_assert (lists_equal (&list1, ©1));
1239 _dbus_list_copy (&list2, ©2);
1240 verify_list (&list2);
1241 verify_list (©2);
1242 _dbus_assert (lists_equal (&list2, ©2));
1244 /* Now test copying empty lists */
1245 _dbus_list_clear (&list1);
1246 _dbus_list_clear (&list2);
1247 _dbus_list_clear (©1);
1248 _dbus_list_clear (©2);
1250 /* bad pointers, because they are allowed in the copy dest */
1251 copy1 = _DBUS_INT_TO_POINTER (0x342234);
1252 copy2 = _DBUS_INT_TO_POINTER (23);
1254 _dbus_list_copy (&list1, ©1);
1255 verify_list (&list1);
1256 verify_list (©1);
1257 _dbus_assert (lists_equal (&list1, ©1));
1259 _dbus_list_copy (&list2, ©2);
1260 verify_list (&list2);
1261 verify_list (©2);
1262 _dbus_assert (lists_equal (&list2, ©2));
1264 _dbus_list_clear (&list1);
1265 _dbus_list_clear (&list2);
1267 /* insert_before on empty list */
1268 _dbus_list_insert_before (&list1, NULL,
1269 _DBUS_INT_TO_POINTER (0));
1270 verify_list (&list1);
1272 /* inserting before first element */
1273 _dbus_list_insert_before (&list1, list1,
1274 _DBUS_INT_TO_POINTER (2));
1275 verify_list (&list1);
1276 _dbus_assert (is_descending_sequence (&list1));
1278 /* inserting in the middle */
1279 _dbus_list_insert_before (&list1, list1->next,
1280 _DBUS_INT_TO_POINTER (1));
1281 verify_list (&list1);
1282 _dbus_assert (is_descending_sequence (&list1));
1284 /* using insert_before to append */
1285 _dbus_list_insert_before (&list1, NULL,
1286 _DBUS_INT_TO_POINTER (-1));
1287 verify_list (&list1);
1288 _dbus_assert (is_descending_sequence (&list1));
1290 _dbus_list_clear (&list1);
1292 /* insert_after on empty list */
1293 _dbus_list_insert_after (&list1, NULL,
1294 _DBUS_INT_TO_POINTER (0));
1295 verify_list (&list1);
1297 /* inserting after first element */
1298 _dbus_list_insert_after (&list1, list1,
1299 _DBUS_INT_TO_POINTER (1));
1300 verify_list (&list1);
1301 _dbus_assert (is_ascending_sequence (&list1));
1303 /* inserting at the end */
1304 _dbus_list_insert_after (&list1, list1->next,
1305 _DBUS_INT_TO_POINTER (2));
1306 verify_list (&list1);
1307 _dbus_assert (is_ascending_sequence (&list1));
1309 /* using insert_after to prepend */
1310 _dbus_list_insert_after (&list1, NULL,
1311 _DBUS_INT_TO_POINTER (-1));
1312 verify_list (&list1);
1313 _dbus_assert (is_ascending_sequence (&list1));
1315 _dbus_list_clear (&list1);
1317 /* using remove_last */
1318 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2));
1319 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1));
1320 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3));
1322 _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2));
1324 verify_list (&list1);
1325 _dbus_assert (is_ascending_sequence (&list1));
1327 _dbus_list_clear (&list1);