4a287d71d61bf3e0bb3393b96d1f6c7a4fb71a62
[ircu2.10.12-pk.git] / libs / dbprim / tests / t_ll_add.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
33 #define DEADINT 0xdeadbeef
34 #define DEADPTR (void *)0xdeadbeef
35
36 /* Check return value of add operation and report PASS/FAIL */
37 static void
38 check_result(unsigned long result, unsigned long expected, char *test,
39              char *info, int die)
40 {
41   if (result != expected) {
42     printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
43            result, expected);
44     if (die)
45       exit(0);
46   } else
47     printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
48 }
49
50 /* Check that a list head matches expectations */
51 static void
52 check_list(link_head_t *list, unsigned int count, link_elem_t *head,
53            link_elem_t *tail, char *test, char *info)
54 {
55   if (list->lh_count != count) { /* Check count first */
56     printf("FAIL/%s_count:%s: Count mismatch\n", test, info);
57     exit(0);
58   } else
59     printf("PASS/%s_count:%s: Counts match\n", test, info);
60
61   if (list->lh_first != head) { /* then check the head pointer */
62     printf("FAIL/%s_first:%s: Head pointer mismatch\n", test, info);
63     exit(0);
64   } else
65     printf("PASS/%s_first:%s: Head pointers match\n", test, info);
66
67   if (list->lh_last != tail) { /* finally check the tail pointer */
68     printf("FAIL/%s_last:%s: Tail pointer mismatch\n", test, info);
69     exit(0);
70   } else
71     printf("PASS/%s_last:%s: Tail pointers match\n", test, info);
72 }
73
74 /* Check that a list element matches expectations */
75 static void
76 check_elem(link_elem_t *elem, link_elem_t *prev, link_elem_t *next,
77            link_head_t *head, char *test, char *info)
78 {
79   if (elem->le_next != next) { /* check next pointer first */
80     printf("FAIL/%s_next:%s: Next pointer mismatch\n", test, info);
81     exit(0);
82   } else
83     printf("PASS/%s_next:%s: Next pointers match\n", test, info);
84
85   if (elem->le_prev != prev) { /* then check prev pointer */
86     printf("FAIL/%s_prev:%s: Prev pointer mismatch\n", test, info);
87     exit(0);
88   } else
89     printf("PASS/%s_prev:%s: Prev pointers match\n", test, info);
90
91   if (elem->le_head != head) { /* finally check list head pointer */
92     printf("FAIL/%s_head:%s: Head pointer mismatch\n", test, info);
93     exit(0);
94   } else
95     printf("PASS/%s_head:%s: Head pointers match\n", test, info);
96 }
97
98 int
99 main(int argc, char **argv)
100 {
101   link_head_t list[] = { /* some lists to operate on */
102     LINK_HEAD_INIT(0),
103     LINK_HEAD_INIT(0),
104     { DEADINT, DEADINT, DEADPTR, DEADPTR, 0 } /* list[2] is a bad list */
105   };
106   link_elem_t elem[] = { /* some elements to operate on */
107     LINK_ELEM_INIT(OBJECT0),
108     LINK_ELEM_INIT(OBJECT1),
109     LINK_ELEM_INIT(OBJECT2),
110     LINK_ELEM_INIT(OBJECT3),
111     LINK_ELEM_INIT(OBJECT4),
112     LINK_ELEM_INIT(OBJECT5),
113     { DEADINT, DEADPTR, DEADPTR, DEADPTR, DEADPTR, DEADINT } /* elem[6] */
114   };
115
116   /* Check the cases that yield "BADARGS" */
117   check_result(ll_add(0, 0, LINK_LOC_HEAD, 0), DB_ERR_BADARGS,
118                "ll_add_noargs", "ll_add() with no arguments", 0);
119   check_result(ll_add(&list[2], &elem[0], LINK_LOC_HEAD, 0), DB_ERR_BADARGS,
120                "ll_add_badlist", "ll_add() with bad list", 0);
121   check_result(ll_add(&list[0], &elem[6], LINK_LOC_HEAD, 0), DB_ERR_BADARGS,
122                "ll_add_badnew", "ll_add() with bad new element", 0);
123   check_result(ll_add(&list[0], &elem[0], LINK_LOC_HEAD, &elem[6]),
124                DB_ERR_BADARGS, "ll_add_badelem", "ll_add() with bad element",
125                0);
126   check_result(ll_add(&list[0], &elem[0], LINK_LOC_BEFORE, 0),
127                DB_ERR_BADARGS, "ll_add_before_noelem",
128                "ll_add() before with no element", 0);
129   check_result(ll_add(&list[0], &elem[0], LINK_LOC_AFTER, 0), DB_ERR_BADARGS,
130                "ll_add_after_noelem", "ll_add() after with no element", 0);
131
132   /* OK, now add an element to one list */
133   check_result(ll_add(&list[0], &elem[0], LINK_LOC_HEAD, 0), 0,
134                "ll_add_l0e0", "ll_add() head list[0] elem[0]", 1);
135
136   /* Verify that it added correctly */
137   check_list(&list[0], 1, &elem[0], &elem[0], "list_l0e0",
138              "List 0 head after first insert");
139   check_elem(&elem[0], 0, 0, &list[0], "elem_l0e0",
140              "Element 0 after first insert");
141
142   /* Now try to add it to a second list */
143   check_result(ll_add(&list[1], &elem[0], LINK_LOC_HEAD, 0), DB_ERR_BUSY,
144                "ll_add_l1e0", "ll_add() head list[1] elem[0]", 1);
145
146   /* OK, now try adding another element to a second list, using TAIL */
147   check_result(ll_add(&list[1], &elem[1], LINK_LOC_TAIL, 0), 0,
148                "ll_add_l1e1", "ll_add() tail list[1] elem[1]", 1);
149
150   /* Verify that it added correctly */
151   check_list(&list[1], 1, &elem[1], &elem[1], "list_l1e1",
152              "List 1 head after second insert");
153   check_elem(&elem[1], 0, 0, &list[1], "elem_l1e1",
154              "Element 1 after second insert");
155
156   /* Now try adding an element to list[0] after an element in list[1] */
157   check_result(ll_add(&list[0], &elem[2], LINK_LOC_AFTER, &elem[1]),
158                DB_ERR_WRONGTABLE, "ll_add_l0e2a1",
159                "ll_add() list[0] elem[2] after elem[1] (list[1])", 1);
160
161   /* Now try adding after an element that hasn't been inserted anywhere */
162   check_result(ll_add(&list[0], &elem[2], LINK_LOC_AFTER, &elem[3]),
163                DB_ERR_UNUSED, "ll_add_l0e2a3",
164                "ll_add() list[0] elem[2] after elem[3] (no list)", 1);
165
166   /* Let's now try adding to the head of a list */
167   check_result(ll_add(&list[0], &elem[2], LINK_LOC_TAIL, 0), 0, "ll_add_l0e2t",
168                "ll_add() tail list[0] elem[2]", 1);
169
170   /* Verify that it added correctly */
171   check_list(&list[0], 2, &elem[0], &elem[2], "list_l0e0e2",
172              "List 0 head after third insert");
173   check_elem(&elem[0], 0, &elem[2], &list[0], "elem_l0e0e2_0",
174              "Element 0 after third insert");
175   check_elem(&elem[2], &elem[0], 0, &list[0], "elem_l0e0e2_2",
176              "Element 2 after third insert");
177
178   /* Now try for the head */
179   check_result(ll_add(&list[1], &elem[3], LINK_LOC_HEAD, 0), 0, "ll_add_l1e3h",
180                "ll_add() head list[1] elem[3]", 1);
181
182   /* Verify that it added correctly */
183   check_list(&list[1], 2, &elem[3], &elem[1], "list_l1e3e1",
184              "List 1 head after fourth insert");
185   check_elem(&elem[1], &elem[3], 0, &list[1], "elem_l1e3e1_1",
186              "Element 1 after fourth insert");
187   check_elem(&elem[3], 0, &elem[1], &list[1], "elem_l1e3e1_3",
188              "Element 3 after fourth insert");
189
190   /* Let's try adding an element in the middle by inserting before last */
191   check_result(ll_add(&list[0], &elem[4], LINK_LOC_BEFORE, ll_last(&list[0])),
192                0, "ll_add_l0e4b2", "ll_add() list[0] elem[4] before elem[2]",
193                1);
194
195   /* Verify that it added correctly */
196   check_list(&list[0], 3, &elem[0], &elem[2], "list_l0e0e4e2",
197              "List 0 head after fifth insert");
198   check_elem(&elem[0], 0, &elem[4], &list[0], "elem_l0e0e4e2_0",
199              "Element 0 after fifth insert");
200   check_elem(&elem[2], &elem[4], 0, &list[0], "elem_l0e0e4e2_2",
201              "Element 2 after fifth insert");
202   check_elem(&elem[4], &elem[0], &elem[2], &list[0], "elem_l0e0e4e2_4",
203              "Element 4 after fifth insert");
204
205   /* OK, now try inserting after first */
206   check_result(ll_add(&list[1], &elem[5], LINK_LOC_AFTER, ll_first(&list[1])),
207                0, "ll_add_l1e5a3", "ll_add() list[1] elem[5] after elem[3]",
208                1);
209
210   /* Verify that it added correctly */
211   check_list(&list[1], 3, &elem[3], &elem[1], "list_l1e3e5e1",
212              "List 1 head after sixth insert");
213   check_elem(&elem[1], &elem[5], 0, &list[1], "elem_l1e3e5e1_1",
214              "Element 1 after sixth insert");
215   check_elem(&elem[3], 0, &elem[5], &list[1], "elem_l1e3e5e1_3",
216              "Element 3 after sixth insert");
217   check_elem(&elem[5], &elem[3], &elem[1], &list[1], "elem_l1e3e5e1_5",
218              "Element 5 after sixth insert");
219
220   return 0;
221 }