|
D-Bus
1.5.8
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-list.c Generic linked list utility (internal to D-Bus implementation) 00003 * 00004 * Copyright (C) 2002 Red Hat, Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 */ 00023 00024 #include <config.h> 00025 #include "dbus-internals.h" 00026 #include "dbus-list.h" 00027 #include "dbus-mempool.h" 00028 #include "dbus-threads-internal.h" 00029 00038 static DBusMemPool *list_pool; 00039 _DBUS_DEFINE_GLOBAL_LOCK (list); 00040 00051 /* the mem pool is probably a speed hit, with the thread 00052 * lock, though it does still save memory - unknown. 00053 */ 00054 static DBusList* 00055 alloc_link (void *data) 00056 { 00057 DBusList *link; 00058 00059 _DBUS_LOCK (list); 00060 00061 if (list_pool == NULL) 00062 { 00063 list_pool = _dbus_mem_pool_new (sizeof (DBusList), TRUE); 00064 00065 if (list_pool == NULL) 00066 { 00067 _DBUS_UNLOCK (list); 00068 return NULL; 00069 } 00070 00071 link = _dbus_mem_pool_alloc (list_pool); 00072 if (link == NULL) 00073 { 00074 _dbus_mem_pool_free (list_pool); 00075 list_pool = NULL; 00076 _DBUS_UNLOCK (list); 00077 return NULL; 00078 } 00079 } 00080 else 00081 { 00082 link = _dbus_mem_pool_alloc (list_pool); 00083 } 00084 00085 if (link) 00086 link->data = data; 00087 00088 _DBUS_UNLOCK (list); 00089 00090 return link; 00091 } 00092 00093 static void 00094 free_link (DBusList *link) 00095 { 00096 _DBUS_LOCK (list); 00097 if (_dbus_mem_pool_dealloc (list_pool, link)) 00098 { 00099 _dbus_mem_pool_free (list_pool); 00100 list_pool = NULL; 00101 } 00102 00103 _DBUS_UNLOCK (list); 00104 } 00105 00106 static void 00107 link_before (DBusList **list, 00108 DBusList *before_this_link, 00109 DBusList *link) 00110 { 00111 if (*list == NULL) 00112 { 00113 link->prev = link; 00114 link->next = link; 00115 *list = link; 00116 } 00117 else 00118 { 00119 link->next = before_this_link; 00120 link->prev = before_this_link->prev; 00121 before_this_link->prev = link; 00122 link->prev->next = link; 00123 00124 if (before_this_link == *list) 00125 *list = link; 00126 } 00127 } 00128 00129 static void 00130 link_after (DBusList **list, 00131 DBusList *after_this_link, 00132 DBusList *link) 00133 { 00134 if (*list == NULL) 00135 { 00136 link->prev = link; 00137 link->next = link; 00138 *list = link; 00139 } 00140 else 00141 { 00142 link->prev = after_this_link; 00143 link->next = after_this_link->next; 00144 after_this_link->next = link; 00145 link->next->prev = link; 00146 } 00147 } 00148 00149 #ifdef DBUS_ENABLE_STATS 00150 void 00151 _dbus_list_get_stats (dbus_uint32_t *in_use_p, 00152 dbus_uint32_t *in_free_list_p, 00153 dbus_uint32_t *allocated_p) 00154 { 00155 _DBUS_LOCK (list); 00156 _dbus_mem_pool_get_stats (list_pool, in_use_p, in_free_list_p, allocated_p); 00157 _DBUS_UNLOCK (list); 00158 } 00159 #endif 00160 00230 DBusList* 00231 _dbus_list_alloc_link (void *data) 00232 { 00233 return alloc_link (data); 00234 } 00235 00242 void 00243 _dbus_list_free_link (DBusList *link) 00244 { 00245 free_link (link); 00246 } 00247 00248 00258 dbus_bool_t 00259 _dbus_list_append (DBusList **list, 00260 void *data) 00261 { 00262 if (!_dbus_list_prepend (list, data)) 00263 return FALSE; 00264 00265 /* Now cycle the list forward one so the prepended node is the tail */ 00266 *list = (*list)->next; 00267 00268 return TRUE; 00269 } 00270 00280 dbus_bool_t 00281 _dbus_list_prepend (DBusList **list, 00282 void *data) 00283 { 00284 DBusList *link; 00285 00286 link = alloc_link (data); 00287 if (link == NULL) 00288 return FALSE; 00289 00290 link_before (list, *list, link); 00291 00292 return TRUE; 00293 } 00294 00303 void 00304 _dbus_list_append_link (DBusList **list, 00305 DBusList *link) 00306 { 00307 _dbus_list_prepend_link (list, link); 00308 00309 /* Now cycle the list forward one so the prepended node is the tail */ 00310 *list = (*list)->next; 00311 } 00312 00321 void 00322 _dbus_list_prepend_link (DBusList **list, 00323 DBusList *link) 00324 { 00325 link_before (list, *list, link); 00326 } 00327 00328 #ifdef DBUS_BUILD_TESTS 00329 00337 dbus_bool_t 00338 _dbus_list_insert_before (DBusList **list, 00339 DBusList *before_this_link, 00340 void *data) 00341 { 00342 DBusList *link; 00343 00344 if (before_this_link == NULL) 00345 return _dbus_list_append (list, data); 00346 else 00347 { 00348 link = alloc_link (data); 00349 if (link == NULL) 00350 return FALSE; 00351 00352 link_before (list, before_this_link, link); 00353 } 00354 00355 return TRUE; 00356 } 00357 #endif /* DBUS_BUILD_TESTS */ 00358 00367 dbus_bool_t 00368 _dbus_list_insert_after (DBusList **list, 00369 DBusList *after_this_link, 00370 void *data) 00371 { 00372 DBusList *link; 00373 00374 if (after_this_link == NULL) 00375 return _dbus_list_prepend (list, data); 00376 else 00377 { 00378 link = alloc_link (data); 00379 if (link == NULL) 00380 return FALSE; 00381 00382 link_after (list, after_this_link, link); 00383 } 00384 00385 return TRUE; 00386 } 00387 00395 void 00396 _dbus_list_insert_before_link (DBusList **list, 00397 DBusList *before_this_link, 00398 DBusList *link) 00399 { 00400 if (before_this_link == NULL) 00401 _dbus_list_append_link (list, link); 00402 else 00403 link_before (list, before_this_link, link); 00404 } 00405 00413 void 00414 _dbus_list_insert_after_link (DBusList **list, 00415 DBusList *after_this_link, 00416 DBusList *link) 00417 { 00418 if (after_this_link == NULL) 00419 _dbus_list_prepend_link (list, link); 00420 else 00421 link_after (list, after_this_link, link); 00422 } 00423 00434 dbus_bool_t 00435 _dbus_list_remove (DBusList **list, 00436 void *data) 00437 { 00438 DBusList *link; 00439 00440 link = *list; 00441 while (link != NULL) 00442 { 00443 if (link->data == data) 00444 { 00445 _dbus_list_remove_link (list, link); 00446 return TRUE; 00447 } 00448 00449 link = _dbus_list_get_next_link (list, link); 00450 } 00451 00452 return FALSE; 00453 } 00454 00465 dbus_bool_t 00466 _dbus_list_remove_last (DBusList **list, 00467 void *data) 00468 { 00469 DBusList *link; 00470 00471 link = _dbus_list_find_last (list, data); 00472 if (link) 00473 { 00474 _dbus_list_remove_link (list, link); 00475 return TRUE; 00476 } 00477 else 00478 return FALSE; 00479 } 00480 00491 DBusList* 00492 _dbus_list_find_last (DBusList **list, 00493 void *data) 00494 { 00495 DBusList *link; 00496 00497 link = _dbus_list_get_last_link (list); 00498 00499 while (link != NULL) 00500 { 00501 if (link->data == data) 00502 return link; 00503 00504 link = _dbus_list_get_prev_link (list, link); 00505 } 00506 00507 return NULL; 00508 } 00509 00518 void 00519 _dbus_list_unlink (DBusList **list, 00520 DBusList *link) 00521 { 00522 if (link->next == link) 00523 { 00524 /* one-element list */ 00525 *list = NULL; 00526 } 00527 else 00528 { 00529 link->prev->next = link->next; 00530 link->next->prev = link->prev; 00531 00532 if (*list == link) 00533 *list = link->next; 00534 } 00535 00536 link->next = NULL; 00537 link->prev = NULL; 00538 } 00539 00546 void 00547 _dbus_list_remove_link (DBusList **list, 00548 DBusList *link) 00549 { 00550 _dbus_list_unlink (list, link); 00551 free_link (link); 00552 } 00553 00561 void 00562 _dbus_list_clear (DBusList **list) 00563 { 00564 DBusList *link; 00565 00566 link = *list; 00567 while (link != NULL) 00568 { 00569 DBusList *next = _dbus_list_get_next_link (list, link); 00570 00571 free_link (link); 00572 00573 link = next; 00574 } 00575 00576 *list = NULL; 00577 } 00578 00586 DBusList* 00587 _dbus_list_get_first_link (DBusList **list) 00588 { 00589 return *list; 00590 } 00591 00599 DBusList* 00600 _dbus_list_get_last_link (DBusList **list) 00601 { 00602 if (*list == NULL) 00603 return NULL; 00604 else 00605 return (*list)->prev; 00606 } 00607 00615 void* 00616 _dbus_list_get_last (DBusList **list) 00617 { 00618 if (*list == NULL) 00619 return NULL; 00620 else 00621 return (*list)->prev->data; 00622 } 00623 00631 void* 00632 _dbus_list_get_first (DBusList **list) 00633 { 00634 if (*list == NULL) 00635 return NULL; 00636 else 00637 return (*list)->data; 00638 } 00639 00647 DBusList* 00648 _dbus_list_pop_first_link (DBusList **list) 00649 { 00650 DBusList *link; 00651 00652 link = _dbus_list_get_first_link (list); 00653 if (link == NULL) 00654 return NULL; 00655 00656 _dbus_list_unlink (list, link); 00657 00658 return link; 00659 } 00660 00668 void* 00669 _dbus_list_pop_first (DBusList **list) 00670 { 00671 DBusList *link; 00672 void *data; 00673 00674 link = _dbus_list_get_first_link (list); 00675 if (link == NULL) 00676 return NULL; 00677 00678 data = link->data; 00679 _dbus_list_remove_link (list, link); 00680 00681 return data; 00682 } 00683 00691 void* 00692 _dbus_list_pop_last (DBusList **list) 00693 { 00694 DBusList *link; 00695 void *data; 00696 00697 link = _dbus_list_get_last_link (list); 00698 if (link == NULL) 00699 return NULL; 00700 00701 data = link->data; 00702 _dbus_list_remove_link (list, link); 00703 00704 return data; 00705 } 00706 00707 #ifdef DBUS_BUILD_TESTS 00708 00715 DBusList* 00716 _dbus_list_pop_last_link (DBusList **list) 00717 { 00718 DBusList *link; 00719 00720 link = _dbus_list_get_last_link (list); 00721 if (link == NULL) 00722 return NULL; 00723 00724 _dbus_list_unlink (list, link); 00725 00726 return link; 00727 } 00728 #endif /* DBUS_BUILD_TESTS */ 00729 00739 dbus_bool_t 00740 _dbus_list_copy (DBusList **list, 00741 DBusList **dest) 00742 { 00743 DBusList *link; 00744 00745 _dbus_assert (list != dest); 00746 00747 *dest = NULL; 00748 00749 link = *list; 00750 while (link != NULL) 00751 { 00752 if (!_dbus_list_append (dest, link->data)) 00753 { 00754 /* free what we have so far */ 00755 _dbus_list_clear (dest); 00756 return FALSE; 00757 } 00758 00759 link = _dbus_list_get_next_link (list, link); 00760 } 00761 00762 return TRUE; 00763 } 00764 00772 int 00773 _dbus_list_get_length (DBusList **list) 00774 { 00775 DBusList *link; 00776 int length; 00777 00778 length = 0; 00779 00780 link = *list; 00781 while (link != NULL) 00782 { 00783 ++length; 00784 00785 link = _dbus_list_get_next_link (list, link); 00786 } 00787 00788 return length; 00789 } 00790 00801 void 00802 _dbus_list_foreach (DBusList **list, 00803 DBusForeachFunction function, 00804 void *data) 00805 { 00806 DBusList *link; 00807 00808 link = *list; 00809 while (link != NULL) 00810 { 00811 DBusList *next = _dbus_list_get_next_link (list, link); 00812 00813 (* function) (link->data, data); 00814 00815 link = next; 00816 } 00817 } 00818 00825 dbus_bool_t 00826 _dbus_list_length_is_one (DBusList **list) 00827 { 00828 return (*list != NULL && 00829 (*list)->next == *list); 00830 } 00831 00834 #ifdef DBUS_BUILD_TESTS 00835 #include "dbus-test.h" 00836 #include <stdio.h> 00837 00838 static void 00839 verify_list (DBusList **list) 00840 { 00841 DBusList *link; 00842 int length; 00843 00844 link = *list; 00845 00846 if (link == NULL) 00847 return; 00848 00849 if (link->next == link) 00850 { 00851 _dbus_assert (link->prev == link); 00852 _dbus_assert (*list == link); 00853 return; 00854 } 00855 00856 length = 0; 00857 do 00858 { 00859 length += 1; 00860 _dbus_assert (link->prev->next == link); 00861 _dbus_assert (link->next->prev == link); 00862 link = link->next; 00863 } 00864 while (link != *list); 00865 00866 _dbus_assert (length == _dbus_list_get_length (list)); 00867 00868 if (length == 1) 00869 _dbus_assert (_dbus_list_length_is_one (list)); 00870 else 00871 _dbus_assert (!_dbus_list_length_is_one (list)); 00872 } 00873 00874 static dbus_bool_t 00875 is_ascending_sequence (DBusList **list) 00876 { 00877 DBusList *link; 00878 int prev; 00879 00880 prev = _DBUS_INT_MIN; 00881 00882 link = _dbus_list_get_first_link (list); 00883 while (link != NULL) 00884 { 00885 int v = _DBUS_POINTER_TO_INT (link->data); 00886 00887 if (v <= prev) 00888 return FALSE; 00889 00890 prev = v; 00891 00892 link = _dbus_list_get_next_link (list, link); 00893 } 00894 00895 return TRUE; 00896 } 00897 00898 static dbus_bool_t 00899 is_descending_sequence (DBusList **list) 00900 { 00901 DBusList *link; 00902 int prev; 00903 00904 prev = _DBUS_INT_MAX; 00905 00906 link = _dbus_list_get_first_link (list); 00907 while (link != NULL) 00908 { 00909 int v = _DBUS_POINTER_TO_INT (link->data); 00910 00911 if (v >= prev) 00912 return FALSE; 00913 00914 prev = v; 00915 00916 link = _dbus_list_get_next_link (list, link); 00917 } 00918 00919 return TRUE; 00920 } 00921 00922 static dbus_bool_t 00923 all_even_values (DBusList **list) 00924 { 00925 DBusList *link; 00926 00927 link = _dbus_list_get_first_link (list); 00928 while (link != NULL) 00929 { 00930 int v = _DBUS_POINTER_TO_INT (link->data); 00931 00932 if ((v % 2) != 0) 00933 return FALSE; 00934 00935 link = _dbus_list_get_next_link (list, link); 00936 } 00937 00938 return TRUE; 00939 } 00940 00941 static dbus_bool_t 00942 all_odd_values (DBusList **list) 00943 { 00944 DBusList *link; 00945 00946 link = _dbus_list_get_first_link (list); 00947 while (link != NULL) 00948 { 00949 int v = _DBUS_POINTER_TO_INT (link->data); 00950 00951 if ((v % 2) == 0) 00952 return FALSE; 00953 00954 link = _dbus_list_get_next_link (list, link); 00955 } 00956 00957 return TRUE; 00958 } 00959 00960 static dbus_bool_t 00961 lists_equal (DBusList **list1, 00962 DBusList **list2) 00963 { 00964 DBusList *link1; 00965 DBusList *link2; 00966 00967 link1 = _dbus_list_get_first_link (list1); 00968 link2 = _dbus_list_get_first_link (list2); 00969 while (link1 && link2) 00970 { 00971 if (link1->data != link2->data) 00972 return FALSE; 00973 00974 link1 = _dbus_list_get_next_link (list1, link1); 00975 link2 = _dbus_list_get_next_link (list2, link2); 00976 } 00977 00978 if (link1 || link2) 00979 return FALSE; 00980 00981 return TRUE; 00982 } 00983 00989 dbus_bool_t 00990 _dbus_list_test (void) 00991 { 00992 DBusList *list1; 00993 DBusList *list2; 00994 DBusList *link1; 00995 DBusList *link2; 00996 DBusList *copy1; 00997 DBusList *copy2; 00998 int i; 00999 01000 list1 = NULL; 01001 list2 = NULL; 01002 01003 /* Test append and prepend */ 01004 01005 i = 0; 01006 while (i < 10) 01007 { 01008 if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) 01009 _dbus_assert_not_reached ("could not allocate for append"); 01010 01011 if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) 01012 _dbus_assert_not_reached ("count not allocate for prepend"); 01013 ++i; 01014 01015 verify_list (&list1); 01016 verify_list (&list2); 01017 01018 _dbus_assert (_dbus_list_get_length (&list1) == i); 01019 _dbus_assert (_dbus_list_get_length (&list2) == i); 01020 } 01021 01022 _dbus_assert (is_ascending_sequence (&list1)); 01023 _dbus_assert (is_descending_sequence (&list2)); 01024 01025 /* Test list clear */ 01026 _dbus_list_clear (&list1); 01027 _dbus_list_clear (&list2); 01028 01029 verify_list (&list1); 01030 verify_list (&list2); 01031 01032 /* Test get_first, get_last, pop_first, pop_last */ 01033 01034 i = 0; 01035 while (i < 10) 01036 { 01037 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01038 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01039 ++i; 01040 } 01041 01042 --i; 01043 while (i >= 0) 01044 { 01045 void *got_data1; 01046 void *got_data2; 01047 01048 void *data1; 01049 void *data2; 01050 01051 got_data1 = _dbus_list_get_last (&list1); 01052 got_data2 = _dbus_list_get_first (&list2); 01053 01054 data1 = _dbus_list_pop_last (&list1); 01055 data2 = _dbus_list_pop_first (&list2); 01056 01057 _dbus_assert (got_data1 == data1); 01058 _dbus_assert (got_data2 == data2); 01059 01060 _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); 01061 _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); 01062 01063 verify_list (&list1); 01064 verify_list (&list2); 01065 01066 _dbus_assert (is_ascending_sequence (&list1)); 01067 _dbus_assert (is_descending_sequence (&list2)); 01068 01069 --i; 01070 } 01071 01072 _dbus_assert (list1 == NULL); 01073 _dbus_assert (list2 == NULL); 01074 01075 /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */ 01076 01077 i = 0; 01078 while (i < 10) 01079 { 01080 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01081 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01082 ++i; 01083 } 01084 01085 --i; 01086 while (i >= 0) 01087 { 01088 DBusList *got_link1; 01089 DBusList *got_link2; 01090 01091 DBusList *link1; 01092 DBusList *link2; 01093 01094 void *data1; 01095 void *data2; 01096 01097 got_link1 = _dbus_list_get_last_link (&list1); 01098 got_link2 = _dbus_list_get_first_link (&list2); 01099 01100 link1 = _dbus_list_pop_last_link (&list1); 01101 link2 = _dbus_list_pop_first_link (&list2); 01102 01103 _dbus_assert (got_link1 == link1); 01104 _dbus_assert (got_link2 == link2); 01105 01106 data1 = link1->data; 01107 data2 = link2->data; 01108 01109 _dbus_list_free_link (link1); 01110 _dbus_list_free_link (link2); 01111 01112 _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); 01113 _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); 01114 01115 verify_list (&list1); 01116 verify_list (&list2); 01117 01118 _dbus_assert (is_ascending_sequence (&list1)); 01119 _dbus_assert (is_descending_sequence (&list2)); 01120 01121 --i; 01122 } 01123 01124 _dbus_assert (list1 == NULL); 01125 _dbus_assert (list2 == NULL); 01126 01127 /* Test iteration */ 01128 01129 i = 0; 01130 while (i < 10) 01131 { 01132 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01133 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01134 ++i; 01135 01136 verify_list (&list1); 01137 verify_list (&list2); 01138 01139 _dbus_assert (_dbus_list_get_length (&list1) == i); 01140 _dbus_assert (_dbus_list_get_length (&list2) == i); 01141 } 01142 01143 _dbus_assert (is_ascending_sequence (&list1)); 01144 _dbus_assert (is_descending_sequence (&list2)); 01145 01146 --i; 01147 link2 = _dbus_list_get_first_link (&list2); 01148 while (link2 != NULL) 01149 { 01150 verify_list (&link2); /* pretend this link is the head */ 01151 01152 _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); 01153 01154 link2 = _dbus_list_get_next_link (&list2, link2); 01155 --i; 01156 } 01157 01158 i = 0; 01159 link1 = _dbus_list_get_first_link (&list1); 01160 while (link1 != NULL) 01161 { 01162 verify_list (&link1); /* pretend this link is the head */ 01163 01164 _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); 01165 01166 link1 = _dbus_list_get_next_link (&list1, link1); 01167 ++i; 01168 } 01169 01170 --i; 01171 link1 = _dbus_list_get_last_link (&list1); 01172 while (link1 != NULL) 01173 { 01174 verify_list (&link1); /* pretend this link is the head */ 01175 01176 _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); 01177 01178 link1 = _dbus_list_get_prev_link (&list1, link1); 01179 --i; 01180 } 01181 01182 _dbus_list_clear (&list1); 01183 _dbus_list_clear (&list2); 01184 01185 /* Test remove */ 01186 01187 i = 0; 01188 while (i < 10) 01189 { 01190 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01191 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01192 ++i; 01193 } 01194 01195 --i; 01196 while (i >= 0) 01197 { 01198 if ((i % 2) == 0) 01199 { 01200 if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) 01201 _dbus_assert_not_reached ("element should have been in list"); 01202 if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) 01203 _dbus_assert_not_reached ("element should have been in list"); 01204 01205 verify_list (&list1); 01206 verify_list (&list2); 01207 } 01208 --i; 01209 } 01210 01211 _dbus_assert (all_odd_values (&list1)); 01212 _dbus_assert (all_odd_values (&list2)); 01213 01214 _dbus_list_clear (&list1); 01215 _dbus_list_clear (&list2); 01216 01217 /* test removing the other half of the elements */ 01218 01219 i = 0; 01220 while (i < 10) 01221 { 01222 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01223 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01224 ++i; 01225 } 01226 01227 --i; 01228 while (i >= 0) 01229 { 01230 if ((i % 2) != 0) 01231 { 01232 if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) 01233 _dbus_assert_not_reached ("element should have been in list"); 01234 if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) 01235 _dbus_assert_not_reached ("element should have been in list"); 01236 01237 verify_list (&list1); 01238 verify_list (&list2); 01239 } 01240 --i; 01241 } 01242 01243 _dbus_assert (all_even_values (&list1)); 01244 _dbus_assert (all_even_values (&list2)); 01245 01246 /* clear list using remove_link */ 01247 while (list1 != NULL) 01248 { 01249 _dbus_list_remove_link (&list1, list1); 01250 verify_list (&list1); 01251 } 01252 while (list2 != NULL) 01253 { 01254 _dbus_list_remove_link (&list2, list2); 01255 verify_list (&list2); 01256 } 01257 01258 /* Test remove link more generally */ 01259 i = 0; 01260 while (i < 10) 01261 { 01262 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01263 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01264 ++i; 01265 } 01266 01267 --i; 01268 link2 = _dbus_list_get_first_link (&list2); 01269 while (link2 != NULL) 01270 { 01271 DBusList *next = _dbus_list_get_next_link (&list2, link2); 01272 01273 _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); 01274 01275 if ((i % 2) == 0) 01276 _dbus_list_remove_link (&list2, link2); 01277 01278 verify_list (&list2); 01279 01280 link2 = next; 01281 --i; 01282 } 01283 01284 _dbus_assert (all_odd_values (&list2)); 01285 _dbus_list_clear (&list2); 01286 01287 i = 0; 01288 link1 = _dbus_list_get_first_link (&list1); 01289 while (link1 != NULL) 01290 { 01291 DBusList *next = _dbus_list_get_next_link (&list1, link1); 01292 01293 _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); 01294 01295 if ((i % 2) != 0) 01296 _dbus_list_remove_link (&list1, link1); 01297 01298 verify_list (&list1); 01299 01300 link1 = next; 01301 ++i; 01302 } 01303 01304 _dbus_assert (all_even_values (&list1)); 01305 _dbus_list_clear (&list1); 01306 01307 /* Test copying a list */ 01308 i = 0; 01309 while (i < 10) 01310 { 01311 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); 01312 _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); 01313 ++i; 01314 } 01315 01316 /* bad pointers, because they are allowed in the copy dest */ 01317 copy1 = _DBUS_INT_TO_POINTER (0x342234); 01318 copy2 = _DBUS_INT_TO_POINTER (23); 01319 01320 _dbus_list_copy (&list1, ©1); 01321 verify_list (&list1); 01322 verify_list (©1); 01323 _dbus_assert (lists_equal (&list1, ©1)); 01324 01325 _dbus_list_copy (&list2, ©2); 01326 verify_list (&list2); 01327 verify_list (©2); 01328 _dbus_assert (lists_equal (&list2, ©2)); 01329 01330 /* Now test copying empty lists */ 01331 _dbus_list_clear (&list1); 01332 _dbus_list_clear (&list2); 01333 _dbus_list_clear (©1); 01334 _dbus_list_clear (©2); 01335 01336 /* bad pointers, because they are allowed in the copy dest */ 01337 copy1 = _DBUS_INT_TO_POINTER (0x342234); 01338 copy2 = _DBUS_INT_TO_POINTER (23); 01339 01340 _dbus_list_copy (&list1, ©1); 01341 verify_list (&list1); 01342 verify_list (©1); 01343 _dbus_assert (lists_equal (&list1, ©1)); 01344 01345 _dbus_list_copy (&list2, ©2); 01346 verify_list (&list2); 01347 verify_list (©2); 01348 _dbus_assert (lists_equal (&list2, ©2)); 01349 01350 _dbus_list_clear (&list1); 01351 _dbus_list_clear (&list2); 01352 01353 /* insert_before on empty list */ 01354 _dbus_list_insert_before (&list1, NULL, 01355 _DBUS_INT_TO_POINTER (0)); 01356 verify_list (&list1); 01357 01358 /* inserting before first element */ 01359 _dbus_list_insert_before (&list1, list1, 01360 _DBUS_INT_TO_POINTER (2)); 01361 verify_list (&list1); 01362 _dbus_assert (is_descending_sequence (&list1)); 01363 01364 /* inserting in the middle */ 01365 _dbus_list_insert_before (&list1, list1->next, 01366 _DBUS_INT_TO_POINTER (1)); 01367 verify_list (&list1); 01368 _dbus_assert (is_descending_sequence (&list1)); 01369 01370 /* using insert_before to append */ 01371 _dbus_list_insert_before (&list1, NULL, 01372 _DBUS_INT_TO_POINTER (-1)); 01373 verify_list (&list1); 01374 _dbus_assert (is_descending_sequence (&list1)); 01375 01376 _dbus_list_clear (&list1); 01377 01378 /* insert_after on empty list */ 01379 _dbus_list_insert_after (&list1, NULL, 01380 _DBUS_INT_TO_POINTER (0)); 01381 verify_list (&list1); 01382 01383 /* inserting after first element */ 01384 _dbus_list_insert_after (&list1, list1, 01385 _DBUS_INT_TO_POINTER (1)); 01386 verify_list (&list1); 01387 _dbus_assert (is_ascending_sequence (&list1)); 01388 01389 /* inserting at the end */ 01390 _dbus_list_insert_after (&list1, list1->next, 01391 _DBUS_INT_TO_POINTER (2)); 01392 verify_list (&list1); 01393 _dbus_assert (is_ascending_sequence (&list1)); 01394 01395 /* using insert_after to prepend */ 01396 _dbus_list_insert_after (&list1, NULL, 01397 _DBUS_INT_TO_POINTER (-1)); 01398 verify_list (&list1); 01399 _dbus_assert (is_ascending_sequence (&list1)); 01400 01401 _dbus_list_clear (&list1); 01402 01403 /* using remove_last */ 01404 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2)); 01405 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1)); 01406 _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3)); 01407 01408 _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2)); 01409 01410 verify_list (&list1); 01411 _dbus_assert (is_ascending_sequence (&list1)); 01412 01413 _dbus_list_clear (&list1); 01414 01415 return TRUE; 01416 } 01417 01418 #endif
1.7.5.1