7c7d91d16c069583b97ec4988c6bb788de5e167a
[ircu2.10.12-pk.git] / libs / dbprim / tests / t_ll_iter.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 <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 #define OBJECT5 (void *)0x56789abc
33
34 #define DEADINT 0xdeadbeef
35 #define DEADPTR (void *)0xdeadbeef
36
37 struct itercheck {
38   link_elem_t *elem_array;
39   int          elem_idx;
40 };
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, char *test, char *info)
60 {
61   if (list->lh_count != count) { /* Check count first */
62     printf("FAIL/%s_count:%s: Count mismatch\n", test, info);
63     exit(0);
64   } else
65     printf("PASS/%s_count:%s: Counts match\n", test, info);
66
67   if (list->lh_first != head) { /* then check the head pointer */
68     printf("FAIL/%s_first:%s: Head pointer mismatch\n", test, info);
69     exit(0);
70   } else
71     printf("PASS/%s_first:%s: Head pointers match\n", test, info);
72
73   if (list->lh_last != tail) { /* finally check the tail pointer */
74     printf("FAIL/%s_last:%s: Tail pointer mismatch\n", test, info);
75     exit(0);
76   } else
77     printf("PASS/%s_last:%s: Tail pointers match\n", test, info);
78 }
79
80 static unsigned long
81 check_iter(link_head_t *head, link_elem_t *elem, void *extra)
82 {
83   struct itercheck *itcheck;
84
85   itcheck = extra;
86
87   /* If we were told to return an error, return one */
88   if (!itcheck->elem_array)
89     return EINVAL;
90
91   /* OK, verify that the list head is the same as the one we expect */
92   if (head != le_head(&itcheck->elem_array[0]))
93     printf("FAIL/ll_iter_funchead_e%d:List heads do not match\n",
94            itcheck->elem_idx);
95   else
96     printf("PASS/ll_iter_funchead_e%d:List heads match\n", itcheck->elem_idx);
97
98   /* Now verify that the element is what we expect. */
99   if (elem != &itcheck->elem_array[itcheck->elem_idx])
100     printf("FAIL/ll_iter_funcelem_e%d:Elements do not match\n",
101            itcheck->elem_idx);
102   else
103     printf("PASS/ll_iter_funcelem_e%d:Elements match\n", itcheck->elem_idx);
104
105   /* Finally, increment the index */
106   itcheck->elem_idx++;
107
108   return 0;
109 }
110
111 int
112 main(int argc, char **argv)
113 {
114   int i;
115   link_head_t list[] = { /* some lists to operate on */
116     LINK_HEAD_INIT(0),
117     { DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[1] 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   };
127   struct itercheck itcheck = { 0, 0 };
128
129   /* First, build the lists */
130   for (i = 0; i < 5; i++)
131     if (ll_add(&list[0], &elem[i], LINK_LOC_TAIL, 0))
132       return -1; /* failed to initialize test */
133
134   /* Baseline checks */
135   check_list(&list[0], 5, &elem[0], &elem[4], "ll_iter_baseline",
136              "Verify baseline list");
137
138   /* Check to see if ll_iter() verifies its arguments correctly */
139   check_result(ll_iter(0, 0, 0), DB_ERR_BADARGS, "ll_iter_noargs",
140                "ll_iter() with no arguments", 0);
141   check_result(ll_iter(&list[1], check_iter, &itcheck), DB_ERR_BADARGS,
142                "ll_iter_badlist", "ll_iter() with bad list", 0);
143   check_result(ll_iter(&list[0], 0, &itcheck), DB_ERR_BADARGS,
144                "ll_iter_badfunc", "ll_iter() with bad function", 0);
145
146   /* Now check to see if ll_iter() returns what the iter function returns */
147   check_result(ll_iter(&list[0], check_iter, &itcheck), EINVAL,
148                "ll_iter_funcreturn",
149                "ll_iter() returning iteration function return value", 0);
150
151   /* Now iterate through the list */
152   itcheck.elem_array = elem;
153   itcheck.elem_idx = 0;
154   check_result(ll_iter(&list[0], check_iter, &itcheck), 0, "ll_iter_function",
155                "ll_iter() iteration", 0);
156
157   /* Did it check them all? */
158   if (itcheck.elem_idx == 5)
159     printf("PASS/ll_iter_func_count:ll_iter() visited all items\n");
160   else
161     printf("FAIL/ll_iter_func_count:ll_iter() visited only %d items\n",
162            itcheck.elem_idx);
163
164   return 0;
165 }