Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / tests / opr / queues-t.c
1 #include <afsconfig.h>
2 #include <afs/param.h>
3
4 #include <stdlib.h>
5
6 #include <tests/tap/basic.h>
7
8 #include <opr/queue.h>
9
10
11 struct charqueue {
12 struct opr_queue entry;
13 char item;
14 };
15
16
17 struct charqueue *
18 newEntry(char string)
19 {
20 struct charqueue *entry;
21
22 entry=malloc(sizeof(struct charqueue));
23 entry->item=string;
24 return(entry);
25 }
26
27 char *
28 queueAsString(struct opr_queue *head) {
29 static char items[255];
30 struct opr_queue *cursor;
31 int pos = 0;
32
33 for(opr_queue_Scan(head, cursor)) {
34 items[pos] = opr_queue_Entry(cursor, struct charqueue, entry)->item;
35 pos++;
36 if (pos==254)
37 break;
38 }
39 items[pos]='\0';
40
41 return items;
42 }
43
44 void
45 stringIntoQueue(char *string, struct opr_queue *q) {
46 int i;
47
48 i = 0;
49 while (string[i]!='\0') {
50 opr_queue_Append(q, &(newEntry(string[i])->entry));
51 i++;
52 }
53 }
54
55 int
56 main(void)
57 {
58 struct opr_queue q1, q2, q3, q4, *cursor;
59
60 plan(20);
61
62 opr_queue_Init(&q1);
63 opr_queue_Init(&q2);
64 opr_queue_Init(&q3);
65 opr_queue_Init(&q4);
66
67 opr_queue_Append(&q1, &(newEntry('A')->entry));
68 opr_queue_Append(&q1, &(newEntry('B')->entry));
69 opr_queue_Append(&q1, &(newEntry('C')->entry));
70 is_string(queueAsString(&q1), "ABC", "Append works as expected");
71
72 opr_queue_Prepend(&q1, &(newEntry('D')->entry));
73 opr_queue_Prepend(&q1, &(newEntry('E')->entry));
74 is_string(queueAsString(&q1), "EDABC", "Prepend works");
75
76 opr_queue_Append(&q2, &(newEntry('1')->entry));
77 opr_queue_Append(&q2, &(newEntry('2')->entry));
78
79 opr_queue_SpliceAppend(&q1, &q2);
80 is_string(queueAsString(&q1), "EDABC12", "SpliceAppend works");
81 ok(opr_queue_IsEmpty(&q2),
82 "IsEmpty works (and splice empties queues)");
83
84 opr_queue_Append(&q2, &(newEntry('8')->entry));
85 opr_queue_Append(&q2, &(newEntry('9')->entry));
86 is_string(queueAsString(&q2), "89", "Append works again");
87
88 opr_queue_SplicePrepend(&q1, &q2);
89 is_string(queueAsString(&q1), "89EDABC12", "SplicePrepend works");
90
91 /* Now for some trickier stuff */
92 stringIntoQueue("XYZ", &q2);
93
94 /* Find the A in the string above */
95 for (opr_queue_Scan(&q1, cursor)) {
96 if (opr_queue_Entry(cursor, struct charqueue, entry)->item == 'A')
97 break;
98 }
99
100 opr_queue_InsertBefore(cursor, &(newEntry('M')->entry));
101 is_string("89EDMABC12", queueAsString(&q1),
102 "InsertBefore functions correctly");
103 opr_queue_SplitBeforeAppend(&q1, &q2, cursor);
104 is_string("ABC12", queueAsString(&q1),
105 "SplitBefore leaves old queue in correct state");
106 is_string("XYZ89EDM", queueAsString(&q2),
107 "SplitBefore correctly appends to new queue");
108
109 /* Find the 9 in q2 */
110 for (opr_queue_Scan(&q2, cursor)) {
111 if (opr_queue_Entry(cursor, struct charqueue, entry)->item == '9')
112 break;
113 }
114 opr_queue_InsertAfter(cursor, &(newEntry('N')->entry));
115 is_string("XYZ89NEDM", queueAsString(&q2), "InsertAfter");
116
117 opr_queue_SplitAfterPrepend(&q2, &q1, cursor);
118 is_string("NEDMABC12", queueAsString(&q1), "SplitAfterPrepend Q1");
119 is_string("XYZ89", queueAsString(&q2), "SplitAfterPrepend Q2");
120
121 /* Swap tests */
122 opr_queue_Swap(&q3, &q4);
123 ok(opr_queue_IsEmpty(&q3) && opr_queue_IsEmpty(&q4), "Swap empty queues");
124
125 opr_queue_Append(&q3, &(newEntry('A')->entry));
126 opr_queue_Append(&q3, &(newEntry('B')->entry));
127 opr_queue_Append(&q3, &(newEntry('C')->entry));
128 opr_queue_Swap(&q3, &q4);
129 ok(opr_queue_IsEmpty(&q3), "Swap with one empty queue Q3");
130 is_string("ABC", queueAsString(&q4), "Swap with one empty queue Q4");
131
132 opr_queue_Append(&q3, &(newEntry('1')->entry));
133 opr_queue_Append(&q3, &(newEntry('2')->entry));
134 opr_queue_Append(&q3, &(newEntry('3')->entry));
135 opr_queue_Swap(&q3, &q4);
136 is_string("ABC", queueAsString(&q3), "Swap Q3");
137 is_string("123", queueAsString(&q4), "Swap Q4");
138
139 /* IsEnd and IsLast handling */
140 ok(opr_queue_IsLast(&q1, &(opr_queue_Last(&q1, struct charqueue, entry)->entry)),
141 "IsLast is true for last element of a list");
142 ok(opr_queue_IsEnd(&q1,
143 opr_queue_Last(&q1, struct charqueue, entry)->entry.next),
144 "IsEnd is true for entry after last element");
145 ok(opr_queue_IsEnd(&q1, &q1), "IsEnd is true for queue head");
146
147 return 0;
148 }