1 |
michael |
3252 |
/* |
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_flush.c,v 1.2 2003/06/12 01:10:11 klmitch Exp $ |
20 |
|
|
*/ |
21 |
|
|
#include <errno.h> |
22 |
|
|
#include <stdio.h> |
23 |
|
|
#include <stdlib.h> |
24 |
|
|
|
25 |
|
|
#include "dbprim.h" |
26 |
|
|
|
27 |
|
|
#define OBJECT0 (void *)0x01234567 |
28 |
|
|
#define OBJECT1 (void *)0x12345678 |
29 |
|
|
#define OBJECT2 (void *)0x23456789 |
30 |
|
|
#define OBJECT3 (void *)0x3456789a |
31 |
|
|
#define OBJECT4 (void *)0x456789ab |
32 |
|
|
|
33 |
|
|
#define OBJECT5 (void *)0x56789abc |
34 |
|
|
#define OBJECT6 (void *)0x6789abcd |
35 |
|
|
#define OBJECT7 (void *)0x789abcde |
36 |
|
|
#define OBJECT8 (void *)0x89abcdef |
37 |
|
|
#define OBJECT9 (void *)0x9abcdef0 |
38 |
|
|
|
39 |
|
|
#define OBJECTA (void *)0xabcdef01 |
40 |
|
|
|
41 |
|
|
#define DEADINT 0xdeadbeef |
42 |
|
|
#define DEADPTR (void *)0xdeadbeef |
43 |
|
|
|
44 |
|
|
struct flushcheck { |
45 |
|
|
link_head_t *elem_list; |
46 |
|
|
link_elem_t *elem_array; |
47 |
|
|
int elem_idx; |
48 |
|
|
}; |
49 |
|
|
|
50 |
|
|
/* Check return value of add operation and report PASS/FAIL */ |
51 |
|
|
static void |
52 |
|
|
check_result(unsigned long result, unsigned long expected, char *test, |
53 |
|
|
char *info, int die) |
54 |
|
|
{ |
55 |
|
|
if (result != expected) { |
56 |
|
|
printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info, |
57 |
|
|
result, expected); |
58 |
|
|
if (die) |
59 |
|
|
exit(0); |
60 |
|
|
} else |
61 |
|
|
printf("PASS/%s:%s correctly returned %lu\n", test, info, result); |
62 |
|
|
} |
63 |
|
|
|
64 |
|
|
/* Check that a list head matches expectations */ |
65 |
|
|
static void |
66 |
|
|
check_list(link_head_t *list, unsigned int count, link_elem_t *head, |
67 |
|
|
link_elem_t *tail, char *test, char *info) |
68 |
|
|
{ |
69 |
|
|
if (list->lh_count != count) { /* Check count first */ |
70 |
|
|
printf("FAIL/%s_count:%s: Count mismatch\n", test, info); |
71 |
|
|
exit(0); |
72 |
|
|
} else |
73 |
|
|
printf("PASS/%s_count:%s: Counts match\n", test, info); |
74 |
|
|
|
75 |
|
|
if (list->lh_first != head) { /* then check the head pointer */ |
76 |
|
|
printf("FAIL/%s_first:%s: Head pointer mismatch\n", test, info); |
77 |
|
|
exit(0); |
78 |
|
|
} else |
79 |
|
|
printf("PASS/%s_first:%s: Head pointers match\n", test, info); |
80 |
|
|
|
81 |
|
|
if (list->lh_last != tail) { /* finally check the tail pointer */ |
82 |
|
|
printf("FAIL/%s_last:%s: Tail pointer mismatch\n", test, info); |
83 |
|
|
exit(0); |
84 |
|
|
} else |
85 |
|
|
printf("PASS/%s_last:%s: Tail pointers match\n", test, info); |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
static unsigned long |
89 |
|
|
check_flush(link_head_t *head, link_elem_t *elem, void *extra) |
90 |
|
|
{ |
91 |
|
|
struct flushcheck *itcheck; |
92 |
|
|
|
93 |
|
|
itcheck = extra; |
94 |
|
|
|
95 |
|
|
/* OK, verify that the list head is the same as the one we expect */ |
96 |
|
|
if (head != itcheck->elem_list) |
97 |
|
|
printf("FAIL/ll_flush_funchead_e%d:List heads do not match\n", |
98 |
|
|
itcheck->elem_idx); |
99 |
|
|
else |
100 |
|
|
printf("PASS/ll_flush_funchead_e%d:List heads match\n", itcheck->elem_idx); |
101 |
|
|
|
102 |
|
|
/* Now verify that the element is what we expect. */ |
103 |
|
|
if (elem != &itcheck->elem_array[itcheck->elem_idx]) |
104 |
|
|
printf("FAIL/ll_flush_funcelem_e%d:Elements do not match\n", |
105 |
|
|
itcheck->elem_idx); |
106 |
|
|
else |
107 |
|
|
printf("PASS/ll_flush_funcelem_e%d:Elements match\n", itcheck->elem_idx); |
108 |
|
|
|
109 |
|
|
/* Increment index and return error if it was 0 */ |
110 |
|
|
return (!itcheck->elem_idx++ ? EINVAL : 0); |
111 |
|
|
} |
112 |
|
|
|
113 |
|
|
int |
114 |
|
|
main(int argc, char **argv) |
115 |
|
|
{ |
116 |
|
|
int i; |
117 |
|
|
link_head_t list[] = { /* some lists to operate on */ |
118 |
|
|
LINK_HEAD_INIT(0), |
119 |
|
|
LINK_HEAD_INIT(0), |
120 |
|
|
{ DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */ |
121 |
|
|
}; |
122 |
|
|
link_elem_t elem[] = { /* some elements to operate on */ |
123 |
|
|
LINK_ELEM_INIT(OBJECT0), |
124 |
|
|
LINK_ELEM_INIT(OBJECT1), |
125 |
|
|
LINK_ELEM_INIT(OBJECT2), |
126 |
|
|
LINK_ELEM_INIT(OBJECT3), |
127 |
|
|
LINK_ELEM_INIT(OBJECT4), |
128 |
|
|
LINK_ELEM_INIT(OBJECT5), |
129 |
|
|
LINK_ELEM_INIT(OBJECT6), |
130 |
|
|
LINK_ELEM_INIT(OBJECT7), |
131 |
|
|
LINK_ELEM_INIT(OBJECT8), |
132 |
|
|
LINK_ELEM_INIT(OBJECT9), |
133 |
|
|
LINK_ELEM_INIT(OBJECTA), |
134 |
|
|
}; |
135 |
|
|
struct flushcheck itcheck = { 0, 0, 0 }; |
136 |
|
|
|
137 |
|
|
/* First, build the lists */ |
138 |
|
|
for (i = 0; i < 5; i++) |
139 |
|
|
if (ll_add(&list[0], &elem[i], LINK_LOC_TAIL, 0) || |
140 |
|
|
ll_add(&list[1], &elem[i + 5], LINK_LOC_TAIL, 0)) |
141 |
|
|
return -1; /* failed to initialize test */ |
142 |
|
|
|
143 |
|
|
/* Baseline checks */ |
144 |
|
|
check_list(&list[0], 5, &elem[0], &elem[4], "ll_flush_baseline_l0", |
145 |
|
|
"Verify baseline list 0"); |
146 |
|
|
check_list(&list[1], 5, &elem[5], &elem[9], "ll_flush_baseline_l1", |
147 |
|
|
"Verify baseline list 1"); |
148 |
|
|
|
149 |
|
|
/* Check to see if ll_flush() verifies its arguments correctly */ |
150 |
|
|
check_result(ll_flush(0, 0, 0), DB_ERR_BADARGS, "ll_flush_noargs", |
151 |
|
|
"ll_flush() with no arguments", 0); |
152 |
|
|
check_result(ll_flush(&list[2], check_flush, &itcheck), DB_ERR_BADARGS, |
153 |
|
|
"ll_flush_badlist", "ll_flush() with bad list", 0); |
154 |
|
|
|
155 |
|
|
/* Check to see if ll_flush() operates properly with no flush function */ |
156 |
|
|
check_result(ll_flush(&list[1], 0, 0), 0, "ll_flush_nofunc", |
157 |
|
|
"ll_flush() with no flush function", 0); |
158 |
|
|
check_list(&list[1], 0, 0, 0, "ll_flush_nofunc", |
159 |
|
|
"Test ll_flush() element removal (no flush function)"); |
160 |
|
|
|
161 |
|
|
/* Now check to see if ll_flush() returns what the flush function returns */ |
162 |
|
|
itcheck.elem_list = &list[0]; |
163 |
|
|
itcheck.elem_array = elem; |
164 |
|
|
itcheck.elem_idx = 0; |
165 |
|
|
check_result(ll_flush(&list[0], check_flush, &itcheck), EINVAL, |
166 |
|
|
"ll_flush_funcreturn", |
167 |
|
|
"ll_flush() returning flush function return value", 0); |
168 |
|
|
check_list(&list[0], 4, &elem[1], &elem[4], "ll_flush_funcreturn", |
169 |
|
|
"Test ll_flush() element removal (function return non-zero)"); |
170 |
|
|
|
171 |
|
|
/* Now flush the list completely */ |
172 |
|
|
check_result(ll_flush(&list[0], check_flush, &itcheck), 0, |
173 |
|
|
"ll_flush_function", "ll_flush() flush", 0); |
174 |
|
|
check_list(&list[0], 0, 0, 0, "ll_flush_function", |
175 |
|
|
"Test ll_flush() element removal (function return zero)"); |
176 |
|
|
|
177 |
|
|
/* Did it check them all? */ |
178 |
|
|
if (itcheck.elem_idx == 5) |
179 |
|
|
printf("PASS/ll_flush_func_count:ll_flush() visited all items\n"); |
180 |
|
|
else |
181 |
|
|
printf("PASS/ll_flush_func_count:ll_flush() visited only %d items\n", |
182 |
|
|
itcheck.elem_idx); |
183 |
|
|
|
184 |
|
|
return 0; |
185 |
|
|
} |