1 |
/* |
2 |
** Copyright (C) 2002 by Kevin L. Mitchell <klmitch@mit.edu> |
3 |
** |
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. |
8 |
** |
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. |
13 |
** |
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, |
17 |
** MA 02111-1307, USA |
18 |
** |
19 |
** @(#)$Id: t_ll_remove.c,v 1.2 2003/06/12 01:10:11 klmitch Exp $ |
20 |
*/ |
21 |
#include <stdio.h> |
22 |
#include <stdlib.h> |
23 |
|
24 |
#include "dbprim.h" |
25 |
|
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 |
34 |
|
35 |
#define OBJECT8 (void *)0x89abcdef |
36 |
|
37 |
#define OBJECT9 (void *)0x9abcdef0 |
38 |
|
39 |
#define DEADINT 0xdeadbeef |
40 |
#define DEADPTR (void *)0xdeadbeef |
41 |
|
42 |
/* Check return value of add operation and report PASS/FAIL */ |
43 |
static void |
44 |
check_result(unsigned long result, unsigned long expected, char *test, |
45 |
char *info, int die) |
46 |
{ |
47 |
if (result != expected) { |
48 |
printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info, |
49 |
result, expected); |
50 |
if (die) |
51 |
exit(0); |
52 |
} else |
53 |
printf("PASS/%s:%s correctly returned %lu\n", test, info, result); |
54 |
} |
55 |
|
56 |
/* Check that a list head matches expectations */ |
57 |
static void |
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) |
60 |
{ |
61 |
if (list->lh_count != count) { /* Check count first */ |
62 |
printf("FAIL/%s_%d_count:%s: Count mismatch\n", test, idx, info); |
63 |
exit(0); |
64 |
} else |
65 |
printf("PASS/%s_%d_count:%s: Counts match\n", test, idx, info); |
66 |
|
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); |
69 |
exit(0); |
70 |
} else |
71 |
printf("PASS/%s_%d_first:%s: Head pointers match\n", test, idx, info); |
72 |
|
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); |
75 |
exit(0); |
76 |
} else |
77 |
printf("PASS/%s_%d_last:%s: Tail pointers match\n", test, idx, info); |
78 |
} |
79 |
|
80 |
/* Check that a list element matches expectations */ |
81 |
static void |
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) |
84 |
{ |
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, |
87 |
e_idx, info); |
88 |
exit(0); |
89 |
} else |
90 |
printf("PASS/%s_%d/%d_next:%s: Next pointers match\n", test, l_idx, e_idx, |
91 |
info); |
92 |
|
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, |
95 |
e_idx, info); |
96 |
exit(0); |
97 |
} else |
98 |
printf("PASS/%s_%d/%d_prev:%s: Prev pointers match\n", test, l_idx, e_idx, |
99 |
info); |
100 |
|
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, |
103 |
e_idx, info); |
104 |
exit(0); |
105 |
} else |
106 |
printf("PASS/%s_%d/%d_head:%s: Head pointers match\n", test, l_idx, e_idx, |
107 |
info); |
108 |
} |
109 |
|
110 |
int |
111 |
main(int argc, char **argv) |
112 |
{ |
113 |
int i; |
114 |
link_head_t list[] = { /* some lists to operate on */ |
115 |
LINK_HEAD_INIT(0), |
116 |
LINK_HEAD_INIT(0), |
117 |
{ DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */ |
118 |
}; |
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] */ |
131 |
}; |
132 |
|
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 */ |
137 |
|
138 |
if (ll_add(&list[1], &elem[8], LINK_LOC_TAIL, 0)) |
139 |
return -1; /* failed to initialize test */ |
140 |
|
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]"); |
146 |
|
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); |
154 |
|
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); |
158 |
|
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", |
162 |
1); |
163 |
|
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"); |
169 |
|
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"); |
177 |
|
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"); |
185 |
|
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"); |
195 |
|
196 |
return 0; |
197 |
} |