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
33 #define DEADINT 0xdeadbeef
34 #define DEADPTR (void *)0xdeadbeef
36 /* Check return value of add operation and report PASS/FAIL */
38 check_result(unsigned long result, unsigned long expected, char *test,
41 if (result != expected) {
42 printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
47 printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
50 /* Check that a list head matches expectations */
52 check_list(link_head_t *list, unsigned int count, link_elem_t *head,
53 link_elem_t *tail, char *test, char *info)
55 if (list->lh_count != count) { /* Check count first */
56 printf("FAIL/%s_count:%s: Count mismatch\n", test, info);
59 printf("PASS/%s_count:%s: Counts match\n", test, info);
61 if (list->lh_first != head) { /* then check the head pointer */
62 printf("FAIL/%s_first:%s: Head pointer mismatch\n", test, info);
65 printf("PASS/%s_first:%s: Head pointers match\n", test, info);
67 if (list->lh_last != tail) { /* finally check the tail pointer */
68 printf("FAIL/%s_last:%s: Tail pointer mismatch\n", test, info);
71 printf("PASS/%s_last:%s: Tail pointers match\n", test, info);
74 /* Check that a list element matches expectations */
76 check_elem(link_elem_t *elem, link_elem_t *prev, link_elem_t *next,
77 link_head_t *head, char *test, char *info)
79 if (elem->le_next != next) { /* check next pointer first */
80 printf("FAIL/%s_next:%s: Next pointer mismatch\n", test, info);
83 printf("PASS/%s_next:%s: Next pointers match\n", test, info);
85 if (elem->le_prev != prev) { /* then check prev pointer */
86 printf("FAIL/%s_prev:%s: Prev pointer mismatch\n", test, info);
89 printf("PASS/%s_prev:%s: Prev pointers match\n", test, info);
91 if (elem->le_head != head) { /* finally check list head pointer */
92 printf("FAIL/%s_head:%s: Head pointer mismatch\n", test, info);
95 printf("PASS/%s_head:%s: Head pointers match\n", test, info);
99 main(int argc, char **argv)
101 link_head_t list[] = { /* some lists to operate on */
104 { DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */
106 link_elem_t elem[] = { /* some elements to operate on */
107 LINK_ELEM_INIT(OBJECT0),
108 LINK_ELEM_INIT(OBJECT1),
109 LINK_ELEM_INIT(OBJECT2),
110 LINK_ELEM_INIT(OBJECT3),
111 LINK_ELEM_INIT(OBJECT4),
112 LINK_ELEM_INIT(OBJECT5),
113 { DEADINT, DEADPTR, DEADPTR, DEADPTR, DEADPTR, DEADINT } /* elem[6] */
116 /* Check the cases that yield "BADARGS" */
117 check_result(ll_add(0, 0, LINK_LOC_HEAD, 0), DB_ERR_BADARGS,
118 "ll_add_noargs", "ll_add() with no arguments", 0);
119 check_result(ll_add(&list[2], &elem[0], LINK_LOC_HEAD, 0), DB_ERR_BADARGS,
120 "ll_add_badlist", "ll_add() with bad list", 0);
121 check_result(ll_add(&list[0], &elem[6], LINK_LOC_HEAD, 0), DB_ERR_BADARGS,
122 "ll_add_badnew", "ll_add() with bad new element", 0);
123 check_result(ll_add(&list[0], &elem[0], LINK_LOC_HEAD, &elem[6]),
124 DB_ERR_BADARGS, "ll_add_badelem", "ll_add() with bad element",
126 check_result(ll_add(&list[0], &elem[0], LINK_LOC_BEFORE, 0),
127 DB_ERR_BADARGS, "ll_add_before_noelem",
128 "ll_add() before with no element", 0);
129 check_result(ll_add(&list[0], &elem[0], LINK_LOC_AFTER, 0), DB_ERR_BADARGS,
130 "ll_add_after_noelem", "ll_add() after with no element", 0);
132 /* OK, now add an element to one list */
133 check_result(ll_add(&list[0], &elem[0], LINK_LOC_HEAD, 0), 0,
134 "ll_add_l0e0", "ll_add() head list[0] elem[0]", 1);
136 /* Verify that it added correctly */
137 check_list(&list[0], 1, &elem[0], &elem[0], "list_l0e0",
138 "List 0 head after first insert");
139 check_elem(&elem[0], 0, 0, &list[0], "elem_l0e0",
140 "Element 0 after first insert");
142 /* Now try to add it to a second list */
143 check_result(ll_add(&list[1], &elem[0], LINK_LOC_HEAD, 0), DB_ERR_BUSY,
144 "ll_add_l1e0", "ll_add() head list[1] elem[0]", 1);
146 /* OK, now try adding another element to a second list, using TAIL */
147 check_result(ll_add(&list[1], &elem[1], LINK_LOC_TAIL, 0), 0,
148 "ll_add_l1e1", "ll_add() tail list[1] elem[1]", 1);
150 /* Verify that it added correctly */
151 check_list(&list[1], 1, &elem[1], &elem[1], "list_l1e1",
152 "List 1 head after second insert");
153 check_elem(&elem[1], 0, 0, &list[1], "elem_l1e1",
154 "Element 1 after second insert");
156 /* Now try adding an element to list[0] after an element in list[1] */
157 check_result(ll_add(&list[0], &elem[2], LINK_LOC_AFTER, &elem[1]),
158 DB_ERR_WRONGTABLE, "ll_add_l0e2a1",
159 "ll_add() list[0] elem[2] after elem[1] (list[1])", 1);
161 /* Now try adding after an element that hasn't been inserted anywhere */
162 check_result(ll_add(&list[0], &elem[2], LINK_LOC_AFTER, &elem[3]),
163 DB_ERR_UNUSED, "ll_add_l0e2a3",
164 "ll_add() list[0] elem[2] after elem[3] (no list)", 1);
166 /* Let's now try adding to the head of a list */
167 check_result(ll_add(&list[0], &elem[2], LINK_LOC_TAIL, 0), 0, "ll_add_l0e2t",
168 "ll_add() tail list[0] elem[2]", 1);
170 /* Verify that it added correctly */
171 check_list(&list[0], 2, &elem[0], &elem[2], "list_l0e0e2",
172 "List 0 head after third insert");
173 check_elem(&elem[0], 0, &elem[2], &list[0], "elem_l0e0e2_0",
174 "Element 0 after third insert");
175 check_elem(&elem[2], &elem[0], 0, &list[0], "elem_l0e0e2_2",
176 "Element 2 after third insert");
178 /* Now try for the head */
179 check_result(ll_add(&list[1], &elem[3], LINK_LOC_HEAD, 0), 0, "ll_add_l1e3h",
180 "ll_add() head list[1] elem[3]", 1);
182 /* Verify that it added correctly */
183 check_list(&list[1], 2, &elem[3], &elem[1], "list_l1e3e1",
184 "List 1 head after fourth insert");
185 check_elem(&elem[1], &elem[3], 0, &list[1], "elem_l1e3e1_1",
186 "Element 1 after fourth insert");
187 check_elem(&elem[3], 0, &elem[1], &list[1], "elem_l1e3e1_3",
188 "Element 3 after fourth insert");
190 /* Let's try adding an element in the middle by inserting before last */
191 check_result(ll_add(&list[0], &elem[4], LINK_LOC_BEFORE, ll_last(&list[0])),
192 0, "ll_add_l0e4b2", "ll_add() list[0] elem[4] before elem[2]",
195 /* Verify that it added correctly */
196 check_list(&list[0], 3, &elem[0], &elem[2], "list_l0e0e4e2",
197 "List 0 head after fifth insert");
198 check_elem(&elem[0], 0, &elem[4], &list[0], "elem_l0e0e4e2_0",
199 "Element 0 after fifth insert");
200 check_elem(&elem[2], &elem[4], 0, &list[0], "elem_l0e0e4e2_2",
201 "Element 2 after fifth insert");
202 check_elem(&elem[4], &elem[0], &elem[2], &list[0], "elem_l0e0e4e2_4",
203 "Element 4 after fifth insert");
205 /* OK, now try inserting after first */
206 check_result(ll_add(&list[1], &elem[5], LINK_LOC_AFTER, ll_first(&list[1])),
207 0, "ll_add_l1e5a3", "ll_add() list[1] elem[5] after elem[3]",
210 /* Verify that it added correctly */
211 check_list(&list[1], 3, &elem[3], &elem[1], "list_l1e3e5e1",
212 "List 1 head after sixth insert");
213 check_elem(&elem[1], &elem[5], 0, &list[1], "elem_l1e3e5e1_1",
214 "Element 1 after sixth insert");
215 check_elem(&elem[3], 0, &elem[5], &list[1], "elem_l1e3e5e1_3",
216 "Element 3 after sixth insert");
217 check_elem(&elem[5], &elem[3], &elem[1], &list[1], "elem_l1e3e5e1_5",
218 "Element 5 after sixth insert");