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
34 #define DEADINT 0xdeadbeef
35 #define DEADPTR (void *)0xdeadbeef
37 /* Check return value of add operation and report PASS/FAIL */
39 check_result(unsigned long result, unsigned long expected, char *test,
42 if (result != expected) {
43 printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
48 printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
51 /* Check that a list head matches expectations */
53 check_list(link_head_t *list, unsigned int count, link_elem_t *head,
54 link_elem_t *tail, char *test, char *info)
56 if (list->lh_count != count) { /* Check count first */
57 printf("FAIL/%s_count:%s: Count mismatch\n", test, info);
60 printf("PASS/%s_count:%s: Counts match\n", test, info);
62 if (list->lh_first != head) { /* then check the head pointer */
63 printf("FAIL/%s_first:%s: Head pointer mismatch\n", test, info);
66 printf("PASS/%s_first:%s: Head pointers match\n", test, info);
68 if (list->lh_last != tail) { /* finally check the tail pointer */
69 printf("FAIL/%s_last:%s: Tail pointer mismatch\n", test, info);
72 printf("PASS/%s_last:%s: Tail pointers match\n", test, info);
75 /* Verify that find found element we were expecting */
77 check_element(link_elem_t *actual, link_elem_t *expected, char *test,
80 if (actual != expected)
81 printf("FAIL/%s_result:%s: Elements don't match\n", test, info);
83 printf("PASS/%s_result:%s: Elements match\n", test, info);
86 /* Comparison function */
88 compare(db_key_t *key, void *value)
90 if (dk_key(key) == value)
97 main(int argc, char **argv)
100 link_head_t list[] = { /* some lists to operate on */
103 { DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */
105 link_elem_t elem[] = { /* some elements to operate on */
106 LINK_ELEM_INIT(OBJECT0),
107 LINK_ELEM_INIT(OBJECT1),
108 LINK_ELEM_INIT(OBJECT2),
109 LINK_ELEM_INIT(OBJECT3),
110 LINK_ELEM_INIT(OBJECT4),
111 LINK_ELEM_INIT(OBJECT5),
112 LINK_ELEM_INIT(OBJECT6),
113 { DEADINT, DEADPTR, DEADPTR, DEADPTR, DEADPTR, DEADINT } /* elem[7] */
115 link_elem_t *res = 0;
116 db_key_t key = DB_KEY_INIT(0, 0);
118 /* First, build the lists */
119 for (i = 0; i < 5; i++)
120 if (ll_add(&list[0], &elem[i], LINK_LOC_TAIL, 0))
121 return -1; /* failed to initialize test */
123 if (ll_add(&list[1], &elem[5], LINK_LOC_TAIL, 0))
124 return -1; /* failed to initialize test */
126 /* Baseline checks */
127 check_list(&list[0], 5, &elem[0], &elem[4], "ll_find_baseline_l0",
128 "Verify baseline list[0]");
129 check_list(&list[1], 1, &elem[5], &elem[5], "ll_find_baseline_l1",
130 "Verify baseline list[1]");
132 /* Check to see if ll_find verifies its arguments correctly */
133 check_result(ll_find(0, 0, 0, 0, 0), DB_ERR_BADARGS, "ll_find_noargs",
134 "ll_find() with no arguments", 0);
135 check_result(ll_find(&list[2], &res, compare, 0, &key), DB_ERR_BADARGS,
136 "ll_find_badlist", "ll_find() with bad list", 0);
137 check_result(ll_find(&list[0], 0, compare, 0, &key), DB_ERR_BADARGS,
138 "ll_find_badresult", "ll_find() with bad result", 0);
139 check_result(ll_find(&list[0], &res, 0, 0, &key), DB_ERR_BADARGS,
140 "ll_find_badcompare", "ll_find() with bad comparison function",
142 check_result(ll_find(&list[0], &res, compare, &elem[7], &key),
143 DB_ERR_BADARGS, "ll_find_badstart",
144 "ll_find() with bad start element", 0);
145 check_result(ll_find(&list[0], &res, compare, 0, 0), DB_ERR_BADARGS,
146 "ll_find_badkey", "ll_find() with bad key", 0);
148 /* OK, verify that it checks that the start element is in the wrong table */
149 check_result(ll_find(&list[0], &res, compare, &elem[5], &key),
150 DB_ERR_WRONGTABLE, "ll_find_wrongtable",
151 "ll_find() with start element in wrong table", 0);
153 /* Next, see if it can find an element that shouldn't be there */
154 check_result(ll_find(&list[0], &res, compare, 0, &key), DB_ERR_NOENTRY,
155 "ll_find_noentry", "ll_find() for non-existant entry", 0);
157 /* OK, try to find an element in a single-entry list */
158 dk_key(&key) = OBJECT5;
159 check_result(ll_find(&list[1], &res, compare, 0, &key), 0,
160 "ll_find_oneentry", "ll_find() for one-entry list", 0);
161 check_element(res, &elem[5], "ll_find_oneentry",
162 "ll_find() for one-entry list");
164 /* Next, try to find the head element... */
165 dk_key(&key) = OBJECT0;
166 check_result(ll_find(&list[0], &res, compare, 0, &key), 0,
167 "ll_find_head", "ll_find() for head", 0);
168 check_element(res, &elem[0], "ll_find_head", "ll_find() for head");
170 /* Now the tail element... */
171 dk_key(&key) = OBJECT4;
172 check_result(ll_find(&list[0], &res, compare, 0, &key), 0,
173 "ll_find_tail", "ll_find() for tail", 0);
174 check_element(res, &elem[4], "ll_find_tail", "ll_find() for tail");
176 /* Next try the middle... */
177 dk_key(&key) = OBJECT2;
178 check_result(ll_find(&list[0], &res, compare, 0, &key), 0,
179 "ll_find_middle", "ll_find() for middle", 0);
180 check_element(res, &elem[2], "ll_find_middle", "ll_find() for middle");
182 /* Now try starting at an arbitrary place in the middle of the list */
183 le_object(&elem[3]) = OBJECT1;
184 dk_key(&key) = OBJECT1;
185 check_result(ll_find(&list[0], &res, compare, &elem[2], &key), 0,
186 "ll_find_start", "ll_find() with start", 0);
187 check_element(res, &elem[3], "ll_find_start", "ll_find() with start");