55cb643ab51ab88e88829238ad18385fdc27b44b
[ircu2.10.12-pk.git] / libs / dbprim / tests / t_ll_find.c
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$
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
34 #define DEADINT 0xdeadbeef
35 #define DEADPTR (void *)0xdeadbeef
36
37 /* Check return value of add operation and report PASS/FAIL */
38 static void
39 check_result(unsigned long result, unsigned long expected, char *test,
40              char *info, int die)
41 {
42   if (result != expected) {
43     printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
44            result, expected);
45     if (die)
46       exit(0);
47   } else
48     printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
49 }
50
51 /* Check that a list head matches expectations */
52 static void
53 check_list(link_head_t *list, unsigned int count, link_elem_t *head,
54            link_elem_t *tail, char *test, char *info)
55 {
56   if (list->lh_count != count) { /* Check count first */
57     printf("FAIL/%s_count:%s: Count mismatch\n", test, info);
58     exit(0);
59   } else
60     printf("PASS/%s_count:%s: Counts match\n", test, info);
61
62   if (list->lh_first != head) { /* then check the head pointer */
63     printf("FAIL/%s_first:%s: Head pointer mismatch\n", test, info);
64     exit(0);
65   } else
66     printf("PASS/%s_first:%s: Head pointers match\n", test, info);
67
68   if (list->lh_last != tail) { /* finally check the tail pointer */
69     printf("FAIL/%s_last:%s: Tail pointer mismatch\n", test, info);
70     exit(0);
71   } else
72     printf("PASS/%s_last:%s: Tail pointers match\n", test, info);
73 }
74
75 /* Verify that find found element we were expecting */
76 static void
77 check_element(link_elem_t *actual, link_elem_t *expected, char *test,
78               char *info)
79 {
80   if (actual != expected)
81     printf("FAIL/%s_result:%s: Elements don't match\n", test, info);
82   else
83     printf("PASS/%s_result:%s: Elements match\n", test, info);
84 }
85
86 /* Comparison function */
87 static unsigned long
88 compare(db_key_t *key, void *value)
89 {
90   if (dk_key(key) == value)
91     return 0;
92
93   return 1;
94 }
95
96 int
97 main(int argc, char **argv)
98 {
99   int i;
100   link_head_t list[] = { /* some lists to operate on */
101     LINK_HEAD_INIT(0),
102     LINK_HEAD_INIT(0),
103     { DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */
104   };
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] */
114   };
115   link_elem_t *res = 0;
116   db_key_t key = DB_KEY_INIT(0, 0);
117
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 */
122
123   if (ll_add(&list[1], &elem[5], LINK_LOC_TAIL, 0))
124     return -1; /* failed to initialize test */
125
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]");
131
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",
141                0);
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);
147
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);
152
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);
156
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");
163
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");
169
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");
175
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");
181
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");
188
189   return 0;
190 }