D-Bus  1.8.2
dbus-list.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-list.c Generic linked list utility (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002 Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
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.
12  *
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.
17  *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 #include <config.h>
25 #include "dbus-internals.h"
26 #include "dbus-list.h"
27 #include "dbus-mempool.h"
28 #include "dbus-threads-internal.h"
29 
38 /* Protected by _DBUS_LOCK (list) */
39 static DBusMemPool *list_pool;
40 
51 /* the mem pool is probably a speed hit, with the thread
52  * lock, though it does still save memory - unknown.
53  */
54 static DBusList*
55 alloc_link (void *data)
56 {
57  DBusList *link;
58 
59  if (!_DBUS_LOCK (list))
60  return FALSE;
61 
62  if (list_pool == NULL)
63  {
64  list_pool = _dbus_mem_pool_new (sizeof (DBusList), TRUE);
65 
66  if (list_pool == NULL)
67  {
68  _DBUS_UNLOCK (list);
69  return NULL;
70  }
71 
72  link = _dbus_mem_pool_alloc (list_pool);
73  if (link == NULL)
74  {
75  _dbus_mem_pool_free (list_pool);
76  list_pool = NULL;
77  _DBUS_UNLOCK (list);
78  return NULL;
79  }
80  }
81  else
82  {
83  link = _dbus_mem_pool_alloc (list_pool);
84  }
85 
86  if (link)
87  link->data = data;
88 
89  _DBUS_UNLOCK (list);
90 
91  return link;
92 }
93 
94 static void
95 free_link (DBusList *link)
96 {
97  if (!_DBUS_LOCK (list))
98  _dbus_assert_not_reached ("we should have initialized global locks "
99  "before we allocated a linked-list link");
100 
101  if (_dbus_mem_pool_dealloc (list_pool, link))
102  {
103  _dbus_mem_pool_free (list_pool);
104  list_pool = NULL;
105  }
106 
107  _DBUS_UNLOCK (list);
108 }
109 
110 static void
111 link_before (DBusList **list,
112  DBusList *before_this_link,
113  DBusList *link)
114 {
115  if (*list == NULL)
116  {
117  link->prev = link;
118  link->next = link;
119  *list = link;
120  }
121  else
122  {
123  link->next = before_this_link;
124  link->prev = before_this_link->prev;
125  before_this_link->prev = link;
126  link->prev->next = link;
127 
128  if (before_this_link == *list)
129  *list = link;
130  }
131 }
132 
133 static void
134 link_after (DBusList **list,
135  DBusList *after_this_link,
136  DBusList *link)
137 {
138  if (*list == NULL)
139  {
140  link->prev = link;
141  link->next = link;
142  *list = link;
143  }
144  else
145  {
146  link->prev = after_this_link;
147  link->next = after_this_link->next;
148  after_this_link->next = link;
149  link->next->prev = link;
150  }
151 }
152 
153 #ifdef DBUS_ENABLE_STATS
154 void
155 _dbus_list_get_stats (dbus_uint32_t *in_use_p,
156  dbus_uint32_t *in_free_list_p,
157  dbus_uint32_t *allocated_p)
158 {
159  if (!_DBUS_LOCK (list))
160  {
161  *in_use_p = 0;
162  *in_free_list_p = 0;
163  *allocated_p = 0;
164  return;
165  }
166 
167  _dbus_mem_pool_get_stats (list_pool, in_use_p, in_free_list_p, allocated_p);
168  _DBUS_UNLOCK (list);
169 }
170 #endif
171 
241 DBusList*
243 {
244  return alloc_link (data);
245 }
246 
253 void
255 {
256  free_link (link);
257 }
258 
259 
271  void *data)
272 {
273  if (!_dbus_list_prepend (list, data))
274  return FALSE;
275 
276  /* Now cycle the list forward one so the prepended node is the tail */
277  *list = (*list)->next;
278 
279  return TRUE;
280 }
281 
293  void *data)
294 {
295  DBusList *link;
296 
297  link = alloc_link (data);
298  if (link == NULL)
299  return FALSE;
300 
301  link_before (list, *list, link);
302 
303  return TRUE;
304 }
305 
314 void
316  DBusList *link)
317 {
318  _dbus_list_prepend_link (list, link);
319 
320  /* Now cycle the list forward one so the prepended node is the tail */
321  *list = (*list)->next;
322 }
323 
332 void
334  DBusList *link)
335 {
336  link_before (list, *list, link);
337 }
338 
349  DBusList *after_this_link,
350  void *data)
351 {
352  DBusList *link;
353 
354  if (after_this_link == NULL)
355  return _dbus_list_prepend (list, data);
356  else
357  {
358  link = alloc_link (data);
359  if (link == NULL)
360  return FALSE;
361 
362  link_after (list, after_this_link, link);
363  }
364 
365  return TRUE;
366 }
367 
375 void
377  DBusList *before_this_link,
378  DBusList *link)
379 {
380  if (before_this_link == NULL)
381  _dbus_list_append_link (list, link);
382  else
383  link_before (list, before_this_link, link);
384 }
385 
393 void
395  DBusList *after_this_link,
396  DBusList *link)
397 {
398  if (after_this_link == NULL)
399  _dbus_list_prepend_link (list, link);
400  else
401  link_after (list, after_this_link, link);
402 }
403 
416  void *data)
417 {
418  DBusList *link;
419 
420  link = *list;
421  while (link != NULL)
422  {
423  if (link->data == data)
424  {
425  _dbus_list_remove_link (list, link);
426  return TRUE;
427  }
428 
429  link = _dbus_list_get_next_link (list, link);
430  }
431 
432  return FALSE;
433 }
434 
447  void *data)
448 {
449  DBusList *link;
450 
451  link = _dbus_list_find_last (list, data);
452  if (link)
453  {
454  _dbus_list_remove_link (list, link);
455  return TRUE;
456  }
457  else
458  return FALSE;
459 }
460 
471 DBusList*
473  void *data)
474 {
475  DBusList *link;
476 
477  link = _dbus_list_get_first_link (list);
478 
479  while (link != NULL)
480  {
481  if (link->data == data)
482  return link;
483 
484  link = _dbus_list_get_next_link (list, link);
485  }
486 
487  return NULL;
488 }
489 
500 DBusList*
502  void *data)
503 {
504  DBusList *link;
505 
506  link = _dbus_list_get_last_link (list);
507 
508  while (link != NULL)
509  {
510  if (link->data == data)
511  return link;
512 
513  link = _dbus_list_get_prev_link (list, link);
514  }
515 
516  return NULL;
517 }
518 
527 void
529  DBusList *link)
530 {
531  if (link->next == link)
532  {
533  /* one-element list */
534  *list = NULL;
535  }
536  else
537  {
538  link->prev->next = link->next;
539  link->next->prev = link->prev;
540 
541  if (*list == link)
542  *list = link->next;
543  }
544 
545  link->next = NULL;
546  link->prev = NULL;
547 }
548 
555 void
557  DBusList *link)
558 {
559  _dbus_list_unlink (list, link);
560  free_link (link);
561 }
562 
570 void
572 {
573  DBusList *link;
574 
575  link = *list;
576  while (link != NULL)
577  {
578  DBusList *next = _dbus_list_get_next_link (list, link);
579 
580  free_link (link);
581 
582  link = next;
583  }
584 
585  *list = NULL;
586 }
587 
595 DBusList*
597 {
598  return *list;
599 }
600 
608 DBusList*
610 {
611  if (*list == NULL)
612  return NULL;
613  else
614  return (*list)->prev;
615 }
616 
624 void*
626 {
627  if (*list == NULL)
628  return NULL;
629  else
630  return (*list)->prev->data;
631 }
632 
640 void*
642 {
643  if (*list == NULL)
644  return NULL;
645  else
646  return (*list)->data;
647 }
648 
656 DBusList*
658 {
659  DBusList *link;
660 
661  link = _dbus_list_get_first_link (list);
662  if (link == NULL)
663  return NULL;
664 
665  _dbus_list_unlink (list, link);
666 
667  return link;
668 }
669 
677 void*
679 {
680  DBusList *link;
681  void *data;
682 
683  link = _dbus_list_get_first_link (list);
684  if (link == NULL)
685  return NULL;
686 
687  data = link->data;
688  _dbus_list_remove_link (list, link);
689 
690  return data;
691 }
692 
700 void*
702 {
703  DBusList *link;
704  void *data;
705 
706  link = _dbus_list_get_last_link (list);
707  if (link == NULL)
708  return NULL;
709 
710  data = link->data;
711  _dbus_list_remove_link (list, link);
712 
713  return data;
714 }
715 
727  DBusList **dest)
728 {
729  DBusList *link;
730 
731  _dbus_assert (list != dest);
732 
733  *dest = NULL;
734 
735  link = *list;
736  while (link != NULL)
737  {
738  if (!_dbus_list_append (dest, link->data))
739  {
740  /* free what we have so far */
741  _dbus_list_clear (dest);
742  return FALSE;
743  }
744 
745  link = _dbus_list_get_next_link (list, link);
746  }
747 
748  return TRUE;
749 }
750 
758 int
760 {
761  DBusList *link;
762  int length;
763 
764  length = 0;
765 
766  link = *list;
767  while (link != NULL)
768  {
769  ++length;
770 
771  link = _dbus_list_get_next_link (list, link);
772  }
773 
774  return length;
775 }
776 
787 void
789  DBusForeachFunction function,
790  void *data)
791 {
792  DBusList *link;
793 
794  link = *list;
795  while (link != NULL)
796  {
797  DBusList *next = _dbus_list_get_next_link (list, link);
798 
799  (* function) (link->data, data);
800 
801  link = next;
802  }
803 }
804 
813 {
814  return (*list != NULL &&
815  (*list)->next == *list);
816 }
817 
820 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
821 #include "dbus-test.h"
822 #include <stdio.h>
823 
824 static void
825 verify_list (DBusList **list)
826 {
827  DBusList *link;
828  int length;
829 
830  link = *list;
831 
832  if (link == NULL)
833  return;
834 
835  if (link->next == link)
836  {
837  _dbus_assert (link->prev == link);
838  _dbus_assert (*list == link);
839  return;
840  }
841 
842  length = 0;
843  do
844  {
845  length += 1;
846  _dbus_assert (link->prev->next == link);
847  _dbus_assert (link->next->prev == link);
848  link = link->next;
849  }
850  while (link != *list);
851 
852  _dbus_assert (length == _dbus_list_get_length (list));
853 
854  if (length == 1)
856  else
858 }
859 
860 static dbus_bool_t
861 is_ascending_sequence (DBusList **list)
862 {
863  DBusList *link;
864  int prev;
865 
866  prev = _DBUS_INT_MIN;
867 
868  link = _dbus_list_get_first_link (list);
869  while (link != NULL)
870  {
871  int v = _DBUS_POINTER_TO_INT (link->data);
872 
873  if (v <= prev)
874  return FALSE;
875 
876  prev = v;
877 
878  link = _dbus_list_get_next_link (list, link);
879  }
880 
881  return TRUE;
882 }
883 
884 static dbus_bool_t
885 is_descending_sequence (DBusList **list)
886 {
887  DBusList *link;
888  int prev;
889 
890  prev = _DBUS_INT_MAX;
891 
892  link = _dbus_list_get_first_link (list);
893  while (link != NULL)
894  {
895  int v = _DBUS_POINTER_TO_INT (link->data);
896 
897  if (v >= prev)
898  return FALSE;
899 
900  prev = v;
901 
902  link = _dbus_list_get_next_link (list, link);
903  }
904 
905  return TRUE;
906 }
907 
908 static dbus_bool_t
909 all_even_values (DBusList **list)
910 {
911  DBusList *link;
912 
913  link = _dbus_list_get_first_link (list);
914  while (link != NULL)
915  {
916  int v = _DBUS_POINTER_TO_INT (link->data);
917 
918  if ((v % 2) != 0)
919  return FALSE;
920 
921  link = _dbus_list_get_next_link (list, link);
922  }
923 
924  return TRUE;
925 }
926 
927 static dbus_bool_t
928 all_odd_values (DBusList **list)
929 {
930  DBusList *link;
931 
932  link = _dbus_list_get_first_link (list);
933  while (link != NULL)
934  {
935  int v = _DBUS_POINTER_TO_INT (link->data);
936 
937  if ((v % 2) == 0)
938  return FALSE;
939 
940  link = _dbus_list_get_next_link (list, link);
941  }
942 
943  return TRUE;
944 }
945 
946 static dbus_bool_t
947 lists_equal (DBusList **list1,
948  DBusList **list2)
949 {
950  DBusList *link1;
951  DBusList *link2;
952 
953  link1 = _dbus_list_get_first_link (list1);
954  link2 = _dbus_list_get_first_link (list2);
955  while (link1 && link2)
956  {
957  if (link1->data != link2->data)
958  return FALSE;
959 
960  link1 = _dbus_list_get_next_link (list1, link1);
961  link2 = _dbus_list_get_next_link (list2, link2);
962  }
963 
964  if (link1 || link2)
965  return FALSE;
966 
967  return TRUE;
968 }
969 
976 _dbus_list_test (void)
977 {
978  DBusList *list1;
979  DBusList *list2;
980  DBusList *link1;
981  DBusList *link2;
982  DBusList *copy1;
983  DBusList *copy2;
984  int i;
985 
986  list1 = NULL;
987  list2 = NULL;
988 
989  /* Test append and prepend */
990 
991  i = 0;
992  while (i < 10)
993  {
994  if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)))
995  _dbus_assert_not_reached ("could not allocate for append");
996 
997  if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)))
998  _dbus_assert_not_reached ("count not allocate for prepend");
999  ++i;
1000 
1001  verify_list (&list1);
1002  verify_list (&list2);
1003 
1004  _dbus_assert (_dbus_list_get_length (&list1) == i);
1005  _dbus_assert (_dbus_list_get_length (&list2) == i);
1006  }
1007 
1008  _dbus_assert (is_ascending_sequence (&list1));
1009  _dbus_assert (is_descending_sequence (&list2));
1010 
1011  /* Test list clear */
1012  _dbus_list_clear (&list1);
1013  _dbus_list_clear (&list2);
1014 
1015  verify_list (&list1);
1016  verify_list (&list2);
1017 
1018  /* Test get_first, get_last, pop_first, pop_last */
1019 
1020  i = 0;
1021  while (i < 10)
1022  {
1025  ++i;
1026  }
1027 
1028  --i;
1029  while (i >= 0)
1030  {
1031  void *got_data1;
1032  void *got_data2;
1033 
1034  void *data1;
1035  void *data2;
1036 
1037  got_data1 = _dbus_list_get_last (&list1);
1038  got_data2 = _dbus_list_get_first (&list2);
1039 
1040  data1 = _dbus_list_pop_last (&list1);
1041  data2 = _dbus_list_pop_first (&list2);
1042 
1043  _dbus_assert (got_data1 == data1);
1044  _dbus_assert (got_data2 == data2);
1045 
1046  _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
1047  _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
1048 
1049  verify_list (&list1);
1050  verify_list (&list2);
1051 
1052  _dbus_assert (is_ascending_sequence (&list1));
1053  _dbus_assert (is_descending_sequence (&list2));
1054 
1055  --i;
1056  }
1057 
1058  _dbus_assert (list1 == NULL);
1059  _dbus_assert (list2 == NULL);
1060 
1061  /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */
1062 
1063  i = 0;
1064  while (i < 10)
1065  {
1068  ++i;
1069  }
1070 
1071  --i;
1072  while (i >= 0)
1073  {
1074  DBusList *got_link1;
1075  DBusList *got_link2;
1076 
1077  DBusList *link2;
1078 
1079  void *data1_indirect;
1080  void *data1;
1081  void *data2;
1082 
1083  got_link1 = _dbus_list_get_last_link (&list1);
1084  got_link2 = _dbus_list_get_first_link (&list2);
1085 
1086  link2 = _dbus_list_pop_first_link (&list2);
1087 
1088  _dbus_assert (got_link2 == link2);
1089 
1090  data1_indirect = got_link1->data;
1091  /* this call makes got_link1 invalid */
1092  data1 = _dbus_list_pop_last (&list1);
1093  _dbus_assert (data1 == data1_indirect);
1094  data2 = link2->data;
1095 
1096  _dbus_list_free_link (link2);
1097 
1098  _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
1099  _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
1100 
1101  verify_list (&list1);
1102  verify_list (&list2);
1103 
1104  _dbus_assert (is_ascending_sequence (&list1));
1105  _dbus_assert (is_descending_sequence (&list2));
1106 
1107  --i;
1108  }
1109 
1110  _dbus_assert (list1 == NULL);
1111  _dbus_assert (list2 == NULL);
1112 
1113  /* Test iteration */
1114 
1115  i = 0;
1116  while (i < 10)
1117  {
1120  ++i;
1121 
1122  verify_list (&list1);
1123  verify_list (&list2);
1124 
1125  _dbus_assert (_dbus_list_get_length (&list1) == i);
1126  _dbus_assert (_dbus_list_get_length (&list2) == i);
1127  }
1128 
1129  _dbus_assert (is_ascending_sequence (&list1));
1130  _dbus_assert (is_descending_sequence (&list2));
1131 
1132  --i;
1133  link2 = _dbus_list_get_first_link (&list2);
1134  while (link2 != NULL)
1135  {
1136  verify_list (&link2); /* pretend this link is the head */
1137 
1138  _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
1139 
1140  link2 = _dbus_list_get_next_link (&list2, link2);
1141  --i;
1142  }
1143 
1144  i = 0;
1145  link1 = _dbus_list_get_first_link (&list1);
1146  while (link1 != NULL)
1147  {
1148  verify_list (&link1); /* pretend this link is the head */
1149 
1150  _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1151 
1152  link1 = _dbus_list_get_next_link (&list1, link1);
1153  ++i;
1154  }
1155 
1156  --i;
1157  link1 = _dbus_list_get_last_link (&list1);
1158  while (link1 != NULL)
1159  {
1160  verify_list (&link1); /* pretend this link is the head */
1161 
1162  _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1163 
1164  link1 = _dbus_list_get_prev_link (&list1, link1);
1165  --i;
1166  }
1167 
1168  _dbus_list_clear (&list1);
1169  _dbus_list_clear (&list2);
1170 
1171  /* Test remove */
1172 
1173  i = 0;
1174  while (i < 10)
1175  {
1178  ++i;
1179  }
1180 
1181  --i;
1182  while (i >= 0)
1183  {
1184  if ((i % 2) == 0)
1185  {
1186  if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
1187  _dbus_assert_not_reached ("element should have been in list");
1188  if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
1189  _dbus_assert_not_reached ("element should have been in list");
1190 
1191  verify_list (&list1);
1192  verify_list (&list2);
1193  }
1194  --i;
1195  }
1196 
1197  _dbus_assert (all_odd_values (&list1));
1198  _dbus_assert (all_odd_values (&list2));
1199 
1200  _dbus_list_clear (&list1);
1201  _dbus_list_clear (&list2);
1202 
1203  /* test removing the other half of the elements */
1204 
1205  i = 0;
1206  while (i < 10)
1207  {
1210  ++i;
1211  }
1212 
1213  --i;
1214  while (i >= 0)
1215  {
1216  if ((i % 2) != 0)
1217  {
1218  if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
1219  _dbus_assert_not_reached ("element should have been in list");
1220  if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
1221  _dbus_assert_not_reached ("element should have been in list");
1222 
1223  verify_list (&list1);
1224  verify_list (&list2);
1225  }
1226  --i;
1227  }
1228 
1229  _dbus_assert (all_even_values (&list1));
1230  _dbus_assert (all_even_values (&list2));
1231 
1232  /* clear list using remove_link */
1233  while (list1 != NULL)
1234  {
1235  _dbus_list_remove_link (&list1, list1);
1236  verify_list (&list1);
1237  }
1238  while (list2 != NULL)
1239  {
1240  _dbus_list_remove_link (&list2, list2);
1241  verify_list (&list2);
1242  }
1243 
1244  /* Test remove link more generally */
1245  i = 0;
1246  while (i < 10)
1247  {
1250  ++i;
1251  }
1252 
1253  --i;
1254  link2 = _dbus_list_get_first_link (&list2);
1255  while (link2 != NULL)
1256  {
1257  DBusList *next = _dbus_list_get_next_link (&list2, link2);
1258 
1259  _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
1260 
1261  if ((i % 2) == 0)
1262  _dbus_list_remove_link (&list2, link2);
1263 
1264  verify_list (&list2);
1265 
1266  link2 = next;
1267  --i;
1268  }
1269 
1270  _dbus_assert (all_odd_values (&list2));
1271  _dbus_list_clear (&list2);
1272 
1273  i = 0;
1274  link1 = _dbus_list_get_first_link (&list1);
1275  while (link1 != NULL)
1276  {
1277  DBusList *next = _dbus_list_get_next_link (&list1, link1);
1278 
1279  _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1280 
1281  if ((i % 2) != 0)
1282  _dbus_list_remove_link (&list1, link1);
1283 
1284  verify_list (&list1);
1285 
1286  link1 = next;
1287  ++i;
1288  }
1289 
1290  _dbus_assert (all_even_values (&list1));
1291  _dbus_list_clear (&list1);
1292 
1293  /* Test copying a list */
1294  i = 0;
1295  while (i < 10)
1296  {
1299  ++i;
1300  }
1301 
1302  /* bad pointers, because they are allowed in the copy dest */
1303  copy1 = _DBUS_INT_TO_POINTER (0x342234);
1304  copy2 = _DBUS_INT_TO_POINTER (23);
1305 
1306  _dbus_list_copy (&list1, &copy1);
1307  verify_list (&list1);
1308  verify_list (&copy1);
1309  _dbus_assert (lists_equal (&list1, &copy1));
1310 
1311  _dbus_list_copy (&list2, &copy2);
1312  verify_list (&list2);
1313  verify_list (&copy2);
1314  _dbus_assert (lists_equal (&list2, &copy2));
1315 
1316  /* Now test copying empty lists */
1317  _dbus_list_clear (&list1);
1318  _dbus_list_clear (&list2);
1319  _dbus_list_clear (&copy1);
1320  _dbus_list_clear (&copy2);
1321 
1322  /* bad pointers, because they are allowed in the copy dest */
1323  copy1 = _DBUS_INT_TO_POINTER (0x342234);
1324  copy2 = _DBUS_INT_TO_POINTER (23);
1325 
1326  _dbus_list_copy (&list1, &copy1);
1327  verify_list (&list1);
1328  verify_list (&copy1);
1329  _dbus_assert (lists_equal (&list1, &copy1));
1330 
1331  _dbus_list_copy (&list2, &copy2);
1332  verify_list (&list2);
1333  verify_list (&copy2);
1334  _dbus_assert (lists_equal (&list2, &copy2));
1335 
1336  _dbus_list_clear (&list1);
1337  _dbus_list_clear (&list2);
1338 
1339  /* insert_after on empty list */
1340  _dbus_list_insert_after (&list1, NULL,
1341  _DBUS_INT_TO_POINTER (0));
1342  verify_list (&list1);
1343 
1344  /* inserting after first element */
1345  _dbus_list_insert_after (&list1, list1,
1346  _DBUS_INT_TO_POINTER (1));
1347  verify_list (&list1);
1348  _dbus_assert (is_ascending_sequence (&list1));
1349 
1350  /* inserting at the end */
1351  _dbus_list_insert_after (&list1, list1->next,
1352  _DBUS_INT_TO_POINTER (2));
1353  verify_list (&list1);
1354  _dbus_assert (is_ascending_sequence (&list1));
1355 
1356  /* using insert_after to prepend */
1357  _dbus_list_insert_after (&list1, NULL,
1358  _DBUS_INT_TO_POINTER (-1));
1359  verify_list (&list1);
1360  _dbus_assert (is_ascending_sequence (&list1));
1361 
1362  _dbus_list_clear (&list1);
1363 
1364  /* using remove_last */
1368 
1370 
1371  verify_list (&list1);
1372  _dbus_assert (is_ascending_sequence (&list1));
1373 
1374  _dbus_list_clear (&list1);
1375 
1376  return TRUE;
1377 }
1378 
1379 #endif