2 ** Copyright (C) 2002 by Kevin L. Mitchell <klmitch@mit.edu>
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Library General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2 of the License, or (at your option) any later version.
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Library General Public License for more details.
14 ** You should have received a copy of the GNU Library General Public
15 ** License along with this library; if not, write to the Free
16 ** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 #define OBJECT0 (void *)0x01234567
27 #define OBJECT1 (void *)0x12345678
28 #define OBJECT2 (void *)0x23456789
29 #define OBJECT3 (void *)0x3456789a
30 #define OBJECT4 (void *)0x456789ab
31 #define OBJECT5 (void *)0x56789abc
32 #define OBJECT6 (void *)0x6789abcd
33 #define OBJECT7 (void *)0x789abcde
35 #define OBJECT8 (void *)0x89abcdef
37 #define OBJECT9 (void *)0x9abcdef0
39 #define DEADINT 0xdeadbeef
40 #define DEADPTR (void *)0xdeadbeef
42 /* Check return value of add operation and report PASS/FAIL */
44 check_result(unsigned long result, unsigned long expected, char *test,
47 if (result != expected) {
48 printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
53 printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
56 /* Check that a list head matches expectations */
58 check_list(link_head_t *list, unsigned int count, link_elem_t *head,
59 link_elem_t *tail, int idx, char *test, char *info)
61 if (list->lh_count != count) { /* Check count first */
62 printf("FAIL/%s_%d_count:%s: Count mismatch\n", test, idx, info);
65 printf("PASS/%s_%d_count:%s: Counts match\n", test, idx, info);
67 if (list->lh_first != head) { /* then check the head pointer */
68 printf("FAIL/%s_%d_first:%s: Head pointer mismatch\n", test, idx, info);
71 printf("PASS/%s_%d_first:%s: Head pointers match\n", test, idx, info);
73 if (list->lh_last != tail) { /* finally check the tail pointer */
74 printf("FAIL/%s_%d_last:%s: Tail pointer mismatch\n", test, idx, info);
77 printf("PASS/%s_%d_last:%s: Tail pointers match\n", test, idx, info);
80 /* Check that a list element matches expectations */
82 check_elem(link_elem_t *elem, link_elem_t *prev, link_elem_t *next,
83 link_head_t *head, int l_idx, int e_idx, char *test, char *info)
85 if (elem->le_next != next) { /* check next pointer first */
86 printf("FAIL/%s_%d/%d_next:%s: Next pointer mismatch\n", test, l_idx,
90 printf("PASS/%s_%d/%d_next:%s: Next pointers match\n", test, l_idx, e_idx,
93 if (elem->le_prev != prev) { /* then check prev pointer */
94 printf("FAIL/%s_%d/%d_prev:%s: Prev pointer mismatch\n", test, l_idx,
98 printf("PASS/%s_%d/%d_prev:%s: Prev pointers match\n", test, l_idx, e_idx,
101 if (elem->le_head != head) { /* finally check list head pointer */
102 printf("FAIL/%s_%d/%d_head:%s: Head pointer mismatch\n", test, l_idx,
106 printf("PASS/%s_%d/%d_head:%s: Head pointers match\n", test, l_idx, e_idx,
111 main(int argc, char **argv)
114 link_head_t list[] = { /* some lists to operate on */
117 { DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */
119 link_elem_t elem[] = { /* some elements to operate on */
120 LINK_ELEM_INIT(OBJECT0),
121 LINK_ELEM_INIT(OBJECT1),
122 LINK_ELEM_INIT(OBJECT2),
123 LINK_ELEM_INIT(OBJECT3),
124 LINK_ELEM_INIT(OBJECT4),
125 LINK_ELEM_INIT(OBJECT5),
126 LINK_ELEM_INIT(OBJECT6),
127 LINK_ELEM_INIT(OBJECT7),
128 LINK_ELEM_INIT(OBJECT8),
129 LINK_ELEM_INIT(OBJECT9),
130 { DEADINT, DEADPTR, DEADPTR, DEADPTR, DEADPTR, DEADINT } /* elem[10] */
133 /* First, build the lists */
134 for (i = 0; i < 8; i++)
135 if (ll_add(&list[0], &elem[i], LINK_LOC_TAIL, 0))
136 return -1; /* failed to initialize test */
138 if (ll_add(&list[1], &elem[8], LINK_LOC_TAIL, 0))
139 return -1; /* failed to initialize test */
141 /* Baseline checks */
142 check_list(&list[0], 8, &elem[0], &elem[7], 0, "ll_remove_baseline",
143 "Verify baseline list[0]");
144 check_list(&list[1], 1, &elem[8], &elem[8], 1, "ll_remove_baseline",
145 "Verify baseline list[1]");
147 /* Check to see if ll_remove verifies its arguments correctly */
148 check_result(ll_remove(0, 0), DB_ERR_BADARGS, "ll_remove_noargs",
149 "ll_remove() with no arguments", 0);
150 check_result(ll_remove(&list[2], &elem[0]), DB_ERR_BADARGS,
151 "ll_remove_badlist", "ll_remove() with bad list", 1);
152 check_result(ll_remove(&list[0], &elem[10]), DB_ERR_BADARGS,
153 "ll_remove_badelem", "ll_remove() with bad element", 1);
155 /* Unused element test */
156 check_result(ll_remove(&list[0], &elem[9]), DB_ERR_UNUSED,
157 "ll_remove_unused", "ll_remove() with unused element", 1);
159 /* Wrong list test */
160 check_result(ll_remove(&list[0], &elem[8]), DB_ERR_WRONGTABLE,
161 "ll_remove_wronglist", "ll_remove() with element in wrong list",
164 /* Make sure removing from a one-item list does the right thing */
165 check_result(ll_remove(&list[1], &elem[8]), 0, "ll_remove_l1e8",
166 "Remove an item from one-item list", 1);
167 check_list(&list[1], 0, 0, 0, 1, "ll_remove_l1e8",
168 "Test removal of an item from one-item list");
170 /* Now try removing an item from the head of a longer list */
171 check_result(ll_remove(&list[0], &elem[0]), 0, "ll_remove_l0e0",
172 "Remove an item from head of list", 1);
173 check_list(&list[0], 7, &elem[1], &elem[7], 0, "ll_remove_l0e0",
174 "Test removal of an item from head of list");
175 check_elem(&elem[1], 0, &elem[2], &list[0], 0, 1, "ll_remove_l0e0",
176 "Test removal of an item from head of list");
178 /* Now try the tail... */
179 check_result(ll_remove(&list[0], &elem[7]), 0, "ll_remove_l0e7",
180 "Remove an item from tail of list", 1);
181 check_list(&list[0], 6, &elem[1], &elem[6], 0, "ll_remove_l0e7",
182 "Test removal of an item from tail of list");
183 check_elem(&elem[6], &elem[5], 0, &list[0], 0, 6, "ll_remove_l0e7",
184 "Test removal of an item from tail of list");
186 /* Finally, try the middle of the list */
187 check_result(ll_remove(&list[0], &elem[3]), 0, "ll_remove_l0e3",
188 "Remove an item from middle of list", 1);
189 check_list(&list[0], 5, &elem[1], &elem[6], 0, "ll_remove_l0e3",
190 "Test removal of an item from middle of list");
191 check_elem(&elem[2], &elem[1], &elem[4], &list[0], 0, 2, "ll_remove_l0e3",
192 "Test removal of an item from middle of list");
193 check_elem(&elem[4], &elem[2], &elem[5], &list[0], 0, 4, "ll_remove_l0e3",
194 "Test removal of an item from middle of list");