D-Bus  1.6.12
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 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  _DBUS_LOCK (list);
60 
61  if (list_pool == NULL)
62  {
63  list_pool = _dbus_mem_pool_new (sizeof (DBusList), TRUE);
64 
65  if (list_pool == NULL)
66  {
67  _DBUS_UNLOCK (list);
68  return NULL;
69  }
70 
71  link = _dbus_mem_pool_alloc (list_pool);
72  if (link == NULL)
73  {
74  _dbus_mem_pool_free (list_pool);
75  list_pool = NULL;
76  _DBUS_UNLOCK (list);
77  return NULL;
78  }
79  }
80  else
81  {
82  link = _dbus_mem_pool_alloc (list_pool);
83  }
84 
85  if (link)
86  link->data = data;
87 
88  _DBUS_UNLOCK (list);
89 
90  return link;
91 }
92 
93 static void
94 free_link (DBusList *link)
95 {
96  _DBUS_LOCK (list);
97  if (_dbus_mem_pool_dealloc (list_pool, link))
98  {
99  _dbus_mem_pool_free (list_pool);
100  list_pool = NULL;
101  }
102 
103  _DBUS_UNLOCK (list);
104 }
105 
106 static void
107 link_before (DBusList **list,
108  DBusList *before_this_link,
109  DBusList *link)
110 {
111  if (*list == NULL)
112  {
113  link->prev = link;
114  link->next = link;
115  *list = link;
116  }
117  else
118  {
119  link->next = before_this_link;
120  link->prev = before_this_link->prev;
121  before_this_link->prev = link;
122  link->prev->next = link;
123 
124  if (before_this_link == *list)
125  *list = link;
126  }
127 }
128 
129 static void
130 link_after (DBusList **list,
131  DBusList *after_this_link,
132  DBusList *link)
133 {
134  if (*list == NULL)
135  {
136  link->prev = link;
137  link->next = link;
138  *list = link;
139  }
140  else
141  {
142  link->prev = after_this_link;
143  link->next = after_this_link->next;
144  after_this_link->next = link;
145  link->next->prev = link;
146  }
147 }
148 
149 #ifdef DBUS_ENABLE_STATS
150 void
151 _dbus_list_get_stats (dbus_uint32_t *in_use_p,
152  dbus_uint32_t *in_free_list_p,
153  dbus_uint32_t *allocated_p)
154 {
155  _DBUS_LOCK (list);
156  _dbus_mem_pool_get_stats (list_pool, in_use_p, in_free_list_p, allocated_p);
157  _DBUS_UNLOCK (list);
158 }
159 #endif
160 
230 DBusList*
232 {
233  return alloc_link (data);
234 }
235 
242 void
244 {
245  free_link (link);
246 }
247 
248 
260  void *data)
261 {
262  if (!_dbus_list_prepend (list, data))
263  return FALSE;
264 
265  /* Now cycle the list forward one so the prepended node is the tail */
266  *list = (*list)->next;
267 
268  return TRUE;
269 }
270 
282  void *data)
283 {
284  DBusList *link;
285 
286  link = alloc_link (data);
287  if (link == NULL)
288  return FALSE;
289 
290  link_before (list, *list, link);
291 
292  return TRUE;
293 }
294 
303 void
305  DBusList *link)
306 {
307  _dbus_list_prepend_link (list, link);
308 
309  /* Now cycle the list forward one so the prepended node is the tail */
310  *list = (*list)->next;
311 }
312 
321 void
323  DBusList *link)
324 {
325  link_before (list, *list, link);
326 }
327 
338  DBusList *after_this_link,
339  void *data)
340 {
341  DBusList *link;
342 
343  if (after_this_link == NULL)
344  return _dbus_list_prepend (list, data);
345  else
346  {
347  link = alloc_link (data);
348  if (link == NULL)
349  return FALSE;
350 
351  link_after (list, after_this_link, link);
352  }
353 
354  return TRUE;
355 }
356 
364 void
366  DBusList *before_this_link,
367  DBusList *link)
368 {
369  if (before_this_link == NULL)
370  _dbus_list_append_link (list, link);
371  else
372  link_before (list, before_this_link, link);
373 }
374 
382 void
384  DBusList *after_this_link,
385  DBusList *link)
386 {
387  if (after_this_link == NULL)
388  _dbus_list_prepend_link (list, link);
389  else
390  link_after (list, after_this_link, link);
391 }
392 
405  void *data)
406 {
407  DBusList *link;
408 
409  link = *list;
410  while (link != NULL)
411  {
412  if (link->data == data)
413  {
414  _dbus_list_remove_link (list, link);
415  return TRUE;
416  }
417 
418  link = _dbus_list_get_next_link (list, link);
419  }
420 
421  return FALSE;
422 }
423 
436  void *data)
437 {
438  DBusList *link;
439 
440  link = _dbus_list_find_last (list, data);
441  if (link)
442  {
443  _dbus_list_remove_link (list, link);
444  return TRUE;
445  }
446  else
447  return FALSE;
448 }
449 
460 DBusList*
462  void *data)
463 {
464  DBusList *link;
465 
466  link = _dbus_list_get_last_link (list);
467 
468  while (link != NULL)
469  {
470  if (link->data == data)
471  return link;
472 
473  link = _dbus_list_get_prev_link (list, link);
474  }
475 
476  return NULL;
477 }
478 
487 void
489  DBusList *link)
490 {
491  if (link->next == link)
492  {
493  /* one-element list */
494  *list = NULL;
495  }
496  else
497  {
498  link->prev->next = link->next;
499  link->next->prev = link->prev;
500 
501  if (*list == link)
502  *list = link->next;
503  }
504 
505  link->next = NULL;
506  link->prev = NULL;
507 }
508 
515 void
517  DBusList *link)
518 {
519  _dbus_list_unlink (list, link);
520  free_link (link);
521 }
522 
530 void
532 {
533  DBusList *link;
534 
535  link = *list;
536  while (link != NULL)
537  {
538  DBusList *next = _dbus_list_get_next_link (list, link);
539 
540  free_link (link);
541 
542  link = next;
543  }
544 
545  *list = NULL;
546 }
547 
555 DBusList*
557 {
558  return *list;
559 }
560 
568 DBusList*
570 {
571  if (*list == NULL)
572  return NULL;
573  else
574  return (*list)->prev;
575 }
576 
584 void*
586 {
587  if (*list == NULL)
588  return NULL;
589  else
590  return (*list)->prev->data;
591 }
592 
600 void*
602 {
603  if (*list == NULL)
604  return NULL;
605  else
606  return (*list)->data;
607 }
608 
616 DBusList*
618 {
619  DBusList *link;
620 
621  link = _dbus_list_get_first_link (list);
622  if (link == NULL)
623  return NULL;
624 
625  _dbus_list_unlink (list, link);
626 
627  return link;
628 }
629 
637 void*
639 {
640  DBusList *link;
641  void *data;
642 
643  link = _dbus_list_get_first_link (list);
644  if (link == NULL)
645  return NULL;
646 
647  data = link->data;
648  _dbus_list_remove_link (list, link);
649 
650  return data;
651 }
652 
660 void*
662 {
663  DBusList *link;
664  void *data;
665 
666  link = _dbus_list_get_last_link (list);
667  if (link == NULL)
668  return NULL;
669 
670  data = link->data;
671  _dbus_list_remove_link (list, link);
672 
673  return data;
674 }
675 
687  DBusList **dest)
688 {
689  DBusList *link;
690 
691  _dbus_assert (list != dest);
692 
693  *dest = NULL;
694 
695  link = *list;
696  while (link != NULL)
697  {
698  if (!_dbus_list_append (dest, link->data))
699  {
700  /* free what we have so far */
701  _dbus_list_clear (dest);
702  return FALSE;
703  }
704 
705  link = _dbus_list_get_next_link (list, link);
706  }
707 
708  return TRUE;
709 }
710 
718 int
720 {
721  DBusList *link;
722  int length;
723 
724  length = 0;
725 
726  link = *list;
727  while (link != NULL)
728  {
729  ++length;
730 
731  link = _dbus_list_get_next_link (list, link);
732  }
733 
734  return length;
735 }
736 
747 void
749  DBusForeachFunction function,
750  void *data)
751 {
752  DBusList *link;
753 
754  link = *list;
755  while (link != NULL)
756  {
757  DBusList *next = _dbus_list_get_next_link (list, link);
758 
759  (* function) (link->data, data);
760 
761  link = next;
762  }
763 }
764 
773 {
774  return (*list != NULL &&
775  (*list)->next == *list);
776 }
777 
780 #ifdef DBUS_BUILD_TESTS
781 #include "dbus-test.h"
782 #include <stdio.h>
783 
784 static void
785 verify_list (DBusList **list)
786 {
787  DBusList *link;
788  int length;
789 
790  link = *list;
791 
792  if (link == NULL)
793  return;
794 
795  if (link->next == link)
796  {
797  _dbus_assert (link->prev == link);
798  _dbus_assert (*list == link);
799  return;
800  }
801 
802  length = 0;
803  do
804  {
805  length += 1;
806  _dbus_assert (link->prev->next == link);
807  _dbus_assert (link->next->prev == link);
808  link = link->next;
809  }
810  while (link != *list);
811 
812  _dbus_assert (length == _dbus_list_get_length (list));
813 
814  if (length == 1)
816  else
818 }
819 
820 static dbus_bool_t
821 is_ascending_sequence (DBusList **list)
822 {
823  DBusList *link;
824  int prev;
825 
826  prev = _DBUS_INT_MIN;
827 
828  link = _dbus_list_get_first_link (list);
829  while (link != NULL)
830  {
831  int v = _DBUS_POINTER_TO_INT (link->data);
832 
833  if (v <= prev)
834  return FALSE;
835 
836  prev = v;
837 
838  link = _dbus_list_get_next_link (list, link);
839  }
840 
841  return TRUE;
842 }
843 
844 static dbus_bool_t
845 is_descending_sequence (DBusList **list)
846 {
847  DBusList *link;
848  int prev;
849 
850  prev = _DBUS_INT_MAX;
851 
852  link = _dbus_list_get_first_link (list);
853  while (link != NULL)
854  {
855  int v = _DBUS_POINTER_TO_INT (link->data);
856 
857  if (v >= prev)
858  return FALSE;
859 
860  prev = v;
861 
862  link = _dbus_list_get_next_link (list, link);
863  }
864 
865  return TRUE;
866 }
867 
868 static dbus_bool_t
869 all_even_values (DBusList **list)
870 {
871  DBusList *link;
872 
873  link = _dbus_list_get_first_link (list);
874  while (link != NULL)
875  {
876  int v = _DBUS_POINTER_TO_INT (link->data);
877 
878  if ((v % 2) != 0)
879  return FALSE;
880 
881  link = _dbus_list_get_next_link (list, link);
882  }
883 
884  return TRUE;
885 }
886 
887 static dbus_bool_t
888 all_odd_values (DBusList **list)
889 {
890  DBusList *link;
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 % 2) == 0)
898  return FALSE;
899 
900  link = _dbus_list_get_next_link (list, link);
901  }
902 
903  return TRUE;
904 }
905 
906 static dbus_bool_t
907 lists_equal (DBusList **list1,
908  DBusList **list2)
909 {
910  DBusList *link1;
911  DBusList *link2;
912 
913  link1 = _dbus_list_get_first_link (list1);
914  link2 = _dbus_list_get_first_link (list2);
915  while (link1 && link2)
916  {
917  if (link1->data != link2->data)
918  return FALSE;
919 
920  link1 = _dbus_list_get_next_link (list1, link1);
921  link2 = _dbus_list_get_next_link (list2, link2);
922  }
923 
924  if (link1 || link2)
925  return FALSE;
926 
927  return TRUE;
928 }
929 
936 _dbus_list_test (void)
937 {
938  DBusList *list1;
939  DBusList *list2;
940  DBusList *link1;
941  DBusList *link2;
942  DBusList *copy1;
943  DBusList *copy2;
944  int i;
945 
946  list1 = NULL;
947  list2 = NULL;
948 
949  /* Test append and prepend */
950 
951  i = 0;
952  while (i < 10)
953  {
954  if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)))
955  _dbus_assert_not_reached ("could not allocate for append");
956 
957  if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)))
958  _dbus_assert_not_reached ("count not allocate for prepend");
959  ++i;
960 
961  verify_list (&list1);
962  verify_list (&list2);
963 
964  _dbus_assert (_dbus_list_get_length (&list1) == i);
965  _dbus_assert (_dbus_list_get_length (&list2) == i);
966  }
967 
968  _dbus_assert (is_ascending_sequence (&list1));
969  _dbus_assert (is_descending_sequence (&list2));
970 
971  /* Test list clear */
972  _dbus_list_clear (&list1);
973  _dbus_list_clear (&list2);
974 
975  verify_list (&list1);
976  verify_list (&list2);
977 
978  /* Test get_first, get_last, pop_first, pop_last */
979 
980  i = 0;
981  while (i < 10)
982  {
985  ++i;
986  }
987 
988  --i;
989  while (i >= 0)
990  {
991  void *got_data1;
992  void *got_data2;
993 
994  void *data1;
995  void *data2;
996 
997  got_data1 = _dbus_list_get_last (&list1);
998  got_data2 = _dbus_list_get_first (&list2);
999 
1000  data1 = _dbus_list_pop_last (&list1);
1001  data2 = _dbus_list_pop_first (&list2);
1002 
1003  _dbus_assert (got_data1 == data1);
1004  _dbus_assert (got_data2 == data2);
1005 
1006  _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
1007  _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
1008 
1009  verify_list (&list1);
1010  verify_list (&list2);
1011 
1012  _dbus_assert (is_ascending_sequence (&list1));
1013  _dbus_assert (is_descending_sequence (&list2));
1014 
1015  --i;
1016  }
1017 
1018  _dbus_assert (list1 == NULL);
1019  _dbus_assert (list2 == NULL);
1020 
1021  /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */
1022 
1023  i = 0;
1024  while (i < 10)
1025  {
1028  ++i;
1029  }
1030 
1031  --i;
1032  while (i >= 0)
1033  {
1034  DBusList *got_link1;
1035  DBusList *got_link2;
1036 
1037  DBusList *link2;
1038 
1039  void *data1_indirect;
1040  void *data1;
1041  void *data2;
1042 
1043  got_link1 = _dbus_list_get_last_link (&list1);
1044  got_link2 = _dbus_list_get_first_link (&list2);
1045 
1046  link2 = _dbus_list_pop_first_link (&list2);
1047 
1048  _dbus_assert (got_link2 == link2);
1049 
1050  data1_indirect = got_link1->data;
1051  /* this call makes got_link1 invalid */
1052  data1 = _dbus_list_pop_last (&list1);
1053  _dbus_assert (data1 == data1_indirect);
1054  data2 = link2->data;
1055 
1056  _dbus_list_free_link (link2);
1057 
1058  _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
1059  _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
1060 
1061  verify_list (&list1);
1062  verify_list (&list2);
1063 
1064  _dbus_assert (is_ascending_sequence (&list1));
1065  _dbus_assert (is_descending_sequence (&list2));
1066 
1067  --i;
1068  }
1069 
1070  _dbus_assert (list1 == NULL);
1071  _dbus_assert (list2 == NULL);
1072 
1073  /* Test iteration */
1074 
1075  i = 0;
1076  while (i < 10)
1077  {
1080  ++i;
1081 
1082  verify_list (&list1);
1083  verify_list (&list2);
1084 
1085  _dbus_assert (_dbus_list_get_length (&list1) == i);
1086  _dbus_assert (_dbus_list_get_length (&list2) == i);
1087  }
1088 
1089  _dbus_assert (is_ascending_sequence (&list1));
1090  _dbus_assert (is_descending_sequence (&list2));
1091 
1092  --i;
1093  link2 = _dbus_list_get_first_link (&list2);
1094  while (link2 != NULL)
1095  {
1096  verify_list (&link2); /* pretend this link is the head */
1097 
1098  _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
1099 
1100  link2 = _dbus_list_get_next_link (&list2, link2);
1101  --i;
1102  }
1103 
1104  i = 0;
1105  link1 = _dbus_list_get_first_link (&list1);
1106  while (link1 != NULL)
1107  {
1108  verify_list (&link1); /* pretend this link is the head */
1109 
1110  _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1111 
1112  link1 = _dbus_list_get_next_link (&list1, link1);
1113  ++i;
1114  }
1115 
1116  --i;
1117  link1 = _dbus_list_get_last_link (&list1);
1118  while (link1 != NULL)
1119  {
1120  verify_list (&link1); /* pretend this link is the head */
1121 
1122  _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1123 
1124  link1 = _dbus_list_get_prev_link (&list1, link1);
1125  --i;
1126  }
1127 
1128  _dbus_list_clear (&list1);
1129  _dbus_list_clear (&list2);
1130 
1131  /* Test remove */
1132 
1133  i = 0;
1134  while (i < 10)
1135  {
1138  ++i;
1139  }
1140 
1141  --i;
1142  while (i >= 0)
1143  {
1144  if ((i % 2) == 0)
1145  {
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");
1150 
1151  verify_list (&list1);
1152  verify_list (&list2);
1153  }
1154  --i;
1155  }
1156 
1157  _dbus_assert (all_odd_values (&list1));
1158  _dbus_assert (all_odd_values (&list2));
1159 
1160  _dbus_list_clear (&list1);
1161  _dbus_list_clear (&list2);
1162 
1163  /* test removing the other half of the elements */
1164 
1165  i = 0;
1166  while (i < 10)
1167  {
1170  ++i;
1171  }
1172 
1173  --i;
1174  while (i >= 0)
1175  {
1176  if ((i % 2) != 0)
1177  {
1178  if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
1179  _dbus_assert_not_reached ("element should have been in list");
1180  if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
1181  _dbus_assert_not_reached ("element should have been in list");
1182 
1183  verify_list (&list1);
1184  verify_list (&list2);
1185  }
1186  --i;
1187  }
1188 
1189  _dbus_assert (all_even_values (&list1));
1190  _dbus_assert (all_even_values (&list2));
1191 
1192  /* clear list using remove_link */
1193  while (list1 != NULL)
1194  {
1195  _dbus_list_remove_link (&list1, list1);
1196  verify_list (&list1);
1197  }
1198  while (list2 != NULL)
1199  {
1200  _dbus_list_remove_link (&list2, list2);
1201  verify_list (&list2);
1202  }
1203 
1204  /* Test remove link more generally */
1205  i = 0;
1206  while (i < 10)
1207  {
1210  ++i;
1211  }
1212 
1213  --i;
1214  link2 = _dbus_list_get_first_link (&list2);
1215  while (link2 != NULL)
1216  {
1217  DBusList *next = _dbus_list_get_next_link (&list2, link2);
1218 
1219  _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
1220 
1221  if ((i % 2) == 0)
1222  _dbus_list_remove_link (&list2, link2);
1223 
1224  verify_list (&list2);
1225 
1226  link2 = next;
1227  --i;
1228  }
1229 
1230  _dbus_assert (all_odd_values (&list2));
1231  _dbus_list_clear (&list2);
1232 
1233  i = 0;
1234  link1 = _dbus_list_get_first_link (&list1);
1235  while (link1 != NULL)
1236  {
1237  DBusList *next = _dbus_list_get_next_link (&list1, link1);
1238 
1239  _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
1240 
1241  if ((i % 2) != 0)
1242  _dbus_list_remove_link (&list1, link1);
1243 
1244  verify_list (&list1);
1245 
1246  link1 = next;
1247  ++i;
1248  }
1249 
1250  _dbus_assert (all_even_values (&list1));
1251  _dbus_list_clear (&list1);
1252 
1253  /* Test copying a list */
1254  i = 0;
1255  while (i < 10)
1256  {
1259  ++i;
1260  }
1261 
1262  /* bad pointers, because they are allowed in the copy dest */
1263  copy1 = _DBUS_INT_TO_POINTER (0x342234);
1264  copy2 = _DBUS_INT_TO_POINTER (23);
1265 
1266  _dbus_list_copy (&list1, &copy1);
1267  verify_list (&list1);
1268  verify_list (&copy1);
1269  _dbus_assert (lists_equal (&list1, &copy1));
1270 
1271  _dbus_list_copy (&list2, &copy2);
1272  verify_list (&list2);
1273  verify_list (&copy2);
1274  _dbus_assert (lists_equal (&list2, &copy2));
1275 
1276  /* Now test copying empty lists */
1277  _dbus_list_clear (&list1);
1278  _dbus_list_clear (&list2);
1279  _dbus_list_clear (&copy1);
1280  _dbus_list_clear (&copy2);
1281 
1282  /* bad pointers, because they are allowed in the copy dest */
1283  copy1 = _DBUS_INT_TO_POINTER (0x342234);
1284  copy2 = _DBUS_INT_TO_POINTER (23);
1285 
1286  _dbus_list_copy (&list1, &copy1);
1287  verify_list (&list1);
1288  verify_list (&copy1);
1289  _dbus_assert (lists_equal (&list1, &copy1));
1290 
1291  _dbus_list_copy (&list2, &copy2);
1292  verify_list (&list2);
1293  verify_list (&copy2);
1294  _dbus_assert (lists_equal (&list2, &copy2));
1295 
1296  _dbus_list_clear (&list1);
1297  _dbus_list_clear (&list2);
1298 
1299  /* insert_after on empty list */
1300  _dbus_list_insert_after (&list1, NULL,
1301  _DBUS_INT_TO_POINTER (0));
1302  verify_list (&list1);
1303 
1304  /* inserting after first element */
1305  _dbus_list_insert_after (&list1, list1,
1306  _DBUS_INT_TO_POINTER (1));
1307  verify_list (&list1);
1308  _dbus_assert (is_ascending_sequence (&list1));
1309 
1310  /* inserting at the end */
1311  _dbus_list_insert_after (&list1, list1->next,
1312  _DBUS_INT_TO_POINTER (2));
1313  verify_list (&list1);
1314  _dbus_assert (is_ascending_sequence (&list1));
1315 
1316  /* using insert_after to prepend */
1317  _dbus_list_insert_after (&list1, NULL,
1318  _DBUS_INT_TO_POINTER (-1));
1319  verify_list (&list1);
1320  _dbus_assert (is_ascending_sequence (&list1));
1321 
1322  _dbus_list_clear (&list1);
1323 
1324  /* using remove_last */
1328 
1330 
1331  verify_list (&list1);
1332  _dbus_assert (is_ascending_sequence (&list1));
1333 
1334  _dbus_list_clear (&list1);
1335 
1336  return TRUE;
1337 }
1338 
1339 #endif
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
void * _dbus_list_get_last(DBusList **list)
Gets the last data in the list.
Definition: dbus-list.c:585
dbus_bool_t _dbus_list_prepend(DBusList **list, void *data)
Prepends a value to the list.
Definition: dbus-list.c:281
#define NULL
A null pointer, defined appropriately for C or C++.
void * _dbus_mem_pool_alloc(DBusMemPool *pool)
Allocates an object from the memory pool.
Definition: dbus-mempool.c:214
void * _dbus_list_pop_last(DBusList **list)
Removes the last value in the list and returns it.
Definition: dbus-list.c:661
DBusList * next
Next list node.
Definition: dbus-list.h:37
#define _DBUS_INT_MIN
Minimum value of type &quot;int&quot;.
dbus_bool_t _dbus_list_length_is_one(DBusList **list)
Check whether length is exactly one.
Definition: dbus-list.c:772
DBusList * _dbus_list_get_last_link(DBusList **list)
Gets the last link in the list.
Definition: dbus-list.c:569
DBusList * _dbus_list_find_last(DBusList **list, void *data)
Finds a value in the list.
Definition: dbus-list.c:461
dbus_bool_t _dbus_list_insert_after(DBusList **list, DBusList *after_this_link, void *data)
Inserts data into the list after the given existing link.
Definition: dbus-list.c:337
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:516
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define _DBUS_INT_TO_POINTER(integer)
Safely stuffs an integer into a pointer, to be extracted later with _DBUS_POINTER_TO_INT.
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:304
void * data
Data stored at this element.
Definition: dbus-list.h:38
void _dbus_list_insert_before_link(DBusList **list, DBusList *before_this_link, DBusList *link)
Inserts a link into the list before the given existing link.
Definition: dbus-list.c:365
#define _dbus_list_get_prev_link(list, link)
Gets the previous link in the list, or NULL if there are no more links.
Definition: dbus-list.h:91
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:231
dbus_bool_t _dbus_list_remove(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:404
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:617
dbus_bool_t _dbus_mem_pool_dealloc(DBusMemPool *pool, void *element)
Deallocates an object previously created with _dbus_mem_pool_alloc().
Definition: dbus-mempool.c:347
DBusList * prev
Previous list node.
Definition: dbus-list.h:36
void * _dbus_list_get_first(DBusList **list)
Gets the first data in the list.
Definition: dbus-list.c:601
#define _dbus_list_get_next_link(list, link)
Gets the next link in the list, or NULL if there are no more links.
Definition: dbus-list.h:90
#define _DBUS_INT_MAX
Maximum value of type &quot;int&quot;.
dbus_bool_t _dbus_list_copy(DBusList **list, DBusList **dest)
Copies a list.
Definition: dbus-list.c:686
void _dbus_list_insert_after_link(DBusList **list, DBusList *after_this_link, DBusList *link)
Inserts a link into the list after the given existing link.
Definition: dbus-list.c:383
dbus_bool_t _dbus_list_remove_last(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:435
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:259
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:748
void _dbus_mem_pool_free(DBusMemPool *pool)
Frees a memory pool (and all elements allocated from it).
Definition: dbus-mempool.c:187
#define _DBUS_POINTER_TO_INT(pointer)
Safely casts a void* to an integer; should only be used on void* that actually contain integers...
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:638
Internals fields of DBusMemPool.
Definition: dbus-mempool.c:98
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
#define TRUE
Expands to &quot;1&quot;.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
void _dbus_list_free_link(DBusList *link)
Frees a linked list node allocated with _dbus_list_alloc_link.
Definition: dbus-list.c:243
#define _DBUS_DEFINE_GLOBAL_LOCK(name)
Defines a global lock variable with the given name.
A node in a linked list.
Definition: dbus-list.h:34
void _dbus_list_unlink(DBusList **list, DBusList *link)
Removes the given link from the list, but doesn&#39;t free it.
Definition: dbus-list.c:488
int _dbus_list_get_length(DBusList **list)
Gets the length of a list.
Definition: dbus-list.c:719
void(* DBusForeachFunction)(void *element, void *data)
Used to iterate over each item in a collection, such as a DBusList.
DBusList * _dbus_list_get_first_link(DBusList **list)
Gets the first link in the list.
Definition: dbus-list.c:556
#define FALSE
Expands to &quot;0&quot;.
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:322
#define _DBUS_LOCK(name)
Locks a global lock.
DBusMemPool * _dbus_mem_pool_new(int element_size, dbus_bool_t zero_elements)
Creates a new memory pool, or returns NULL on failure.
Definition: dbus-mempool.c:138
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:531