qapi: Reject section heading in the middle of a doc comment
[qemu/kevin.git] / tests / unit / test-qtree.c
blob4d836d22c717fb1546f7c53a19285c905f01f6b1
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-or-later
4 * Tests for QTree.
5 * Original source: glib
6 * https://gitlab.gnome.org/GNOME/glib/-/blob/main/glib/tests/tree.c
7 * LGPL license.
8 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
9 */
11 #include "qemu/osdep.h"
12 #include "qemu/qtree.h"
14 static gint my_compare(gconstpointer a, gconstpointer b)
16 const char *cha = a;
17 const char *chb = b;
19 return *cha - *chb;
22 static gint my_compare_with_data(gconstpointer a,
23 gconstpointer b,
24 gpointer user_data)
26 const char *cha = a;
27 const char *chb = b;
29 /* just check that we got the right data */
30 g_assert(GPOINTER_TO_INT(user_data) == 123);
32 return *cha - *chb;
35 static gint my_search(gconstpointer a, gconstpointer b)
37 return my_compare(b, a);
40 static gpointer destroyed_key;
41 static gpointer destroyed_value;
42 static guint destroyed_key_count;
43 static guint destroyed_value_count;
45 static void my_key_destroy(gpointer key)
47 destroyed_key = key;
48 destroyed_key_count++;
51 static void my_value_destroy(gpointer value)
53 destroyed_value = value;
54 destroyed_value_count++;
57 static gint my_traverse(gpointer key, gpointer value, gpointer data)
59 char *ch = key;
61 g_assert((*ch) > 0);
63 if (*ch == 'd') {
64 return TRUE;
67 return FALSE;
70 char chars[] =
71 "0123456789"
72 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
73 "abcdefghijklmnopqrstuvwxyz";
75 char chars2[] =
76 "0123456789"
77 "abcdefghijklmnopqrstuvwxyz";
79 static gint check_order(gpointer key, gpointer value, gpointer data)
81 char **p = data;
82 char *ch = key;
84 g_assert(**p == *ch);
86 (*p)++;
88 return FALSE;
91 static void test_tree_search(void)
93 gint i;
94 QTree *tree;
95 gboolean removed;
96 gchar c;
97 gchar *p, *d;
99 tree = q_tree_new_with_data(my_compare_with_data, GINT_TO_POINTER(123));
101 for (i = 0; chars[i]; i++) {
102 q_tree_insert(tree, &chars[i], &chars[i]);
105 q_tree_foreach(tree, my_traverse, NULL);
107 g_assert(q_tree_nnodes(tree) == strlen(chars));
108 g_assert(q_tree_height(tree) == 6);
110 p = chars;
111 q_tree_foreach(tree, check_order, &p);
113 for (i = 0; i < 26; i++) {
114 removed = q_tree_remove(tree, &chars[i + 10]);
115 g_assert(removed);
118 c = '\0';
119 removed = q_tree_remove(tree, &c);
120 g_assert(!removed);
122 q_tree_foreach(tree, my_traverse, NULL);
124 g_assert(q_tree_nnodes(tree) == strlen(chars2));
125 g_assert(q_tree_height(tree) == 6);
127 p = chars2;
128 q_tree_foreach(tree, check_order, &p);
130 for (i = 25; i >= 0; i--) {
131 q_tree_insert(tree, &chars[i + 10], &chars[i + 10]);
134 p = chars;
135 q_tree_foreach(tree, check_order, &p);
137 c = '0';
138 p = q_tree_lookup(tree, &c);
139 g_assert(p && *p == c);
140 g_assert(q_tree_lookup_extended(tree, &c, (gpointer *)&d, (gpointer *)&p));
141 g_assert(c == *d && c == *p);
143 c = 'A';
144 p = q_tree_lookup(tree, &c);
145 g_assert(p && *p == c);
147 c = 'a';
148 p = q_tree_lookup(tree, &c);
149 g_assert(p && *p == c);
151 c = 'z';
152 p = q_tree_lookup(tree, &c);
153 g_assert(p && *p == c);
155 c = '!';
156 p = q_tree_lookup(tree, &c);
157 g_assert(p == NULL);
159 c = '=';
160 p = q_tree_lookup(tree, &c);
161 g_assert(p == NULL);
163 c = '|';
164 p = q_tree_lookup(tree, &c);
165 g_assert(p == NULL);
167 c = '0';
168 p = q_tree_search(tree, my_search, &c);
169 g_assert(p && *p == c);
171 c = 'A';
172 p = q_tree_search(tree, my_search, &c);
173 g_assert(p && *p == c);
175 c = 'a';
176 p = q_tree_search(tree, my_search, &c);
177 g_assert(p && *p == c);
179 c = 'z';
180 p = q_tree_search(tree, my_search, &c);
181 g_assert(p && *p == c);
183 c = '!';
184 p = q_tree_search(tree, my_search, &c);
185 g_assert(p == NULL);
187 c = '=';
188 p = q_tree_search(tree, my_search, &c);
189 g_assert(p == NULL);
191 c = '|';
192 p = q_tree_search(tree, my_search, &c);
193 g_assert(p == NULL);
195 q_tree_destroy(tree);
198 static void test_tree_remove(void)
200 QTree *tree;
201 char c, d;
202 gint i;
203 gboolean removed;
205 tree = q_tree_new_full((GCompareDataFunc)my_compare, NULL,
206 my_key_destroy,
207 my_value_destroy);
209 for (i = 0; chars[i]; i++) {
210 q_tree_insert(tree, &chars[i], &chars[i]);
213 c = '0';
214 q_tree_insert(tree, &c, &c);
215 g_assert(destroyed_key == &c);
216 g_assert(destroyed_value == &chars[0]);
217 destroyed_key = NULL;
218 destroyed_value = NULL;
220 d = '1';
221 q_tree_replace(tree, &d, &d);
222 g_assert(destroyed_key == &chars[1]);
223 g_assert(destroyed_value == &chars[1]);
224 destroyed_key = NULL;
225 destroyed_value = NULL;
227 c = '2';
228 removed = q_tree_remove(tree, &c);
229 g_assert(removed);
230 g_assert(destroyed_key == &chars[2]);
231 g_assert(destroyed_value == &chars[2]);
232 destroyed_key = NULL;
233 destroyed_value = NULL;
235 c = '3';
236 removed = q_tree_steal(tree, &c);
237 g_assert(removed);
238 g_assert(destroyed_key == NULL);
239 g_assert(destroyed_value == NULL);
241 const gchar *remove = "omkjigfedba";
242 for (i = 0; remove[i]; i++) {
243 removed = q_tree_remove(tree, &remove[i]);
244 g_assert(removed);
247 q_tree_destroy(tree);
250 static void test_tree_destroy(void)
252 QTree *tree;
253 gint i;
255 tree = q_tree_new(my_compare);
257 for (i = 0; chars[i]; i++) {
258 q_tree_insert(tree, &chars[i], &chars[i]);
261 g_assert(q_tree_nnodes(tree) == strlen(chars));
263 g_test_message("nnodes: %d", q_tree_nnodes(tree));
264 q_tree_ref(tree);
265 q_tree_destroy(tree);
267 g_test_message("nnodes: %d", q_tree_nnodes(tree));
268 g_assert(q_tree_nnodes(tree) == 0);
270 q_tree_unref(tree);
273 static void test_tree_insert(void)
275 QTree *tree;
276 gchar *p;
277 gint i;
278 gchar *scrambled;
280 tree = q_tree_new(my_compare);
282 for (i = 0; chars[i]; i++) {
283 q_tree_insert(tree, &chars[i], &chars[i]);
285 p = chars;
286 q_tree_foreach(tree, check_order, &p);
288 q_tree_unref(tree);
289 tree = q_tree_new(my_compare);
291 for (i = strlen(chars) - 1; i >= 0; i--) {
292 q_tree_insert(tree, &chars[i], &chars[i]);
294 p = chars;
295 q_tree_foreach(tree, check_order, &p);
297 q_tree_unref(tree);
298 tree = q_tree_new(my_compare);
300 scrambled = g_strdup(chars);
302 for (i = 0; i < 30; i++) {
303 gchar tmp;
304 gint a, b;
306 a = g_random_int_range(0, strlen(scrambled));
307 b = g_random_int_range(0, strlen(scrambled));
308 tmp = scrambled[a];
309 scrambled[a] = scrambled[b];
310 scrambled[b] = tmp;
313 for (i = 0; scrambled[i]; i++) {
314 q_tree_insert(tree, &scrambled[i], &scrambled[i]);
316 p = chars;
317 q_tree_foreach(tree, check_order, &p);
319 g_free(scrambled);
320 q_tree_unref(tree);
323 int main(int argc, char *argv[])
325 g_test_init(&argc, &argv, NULL);
327 g_test_add_func("/qtree/search", test_tree_search);
328 g_test_add_func("/qtree/remove", test_tree_remove);
329 g_test_add_func("/qtree/destroy", test_tree_destroy);
330 g_test_add_func("/qtree/insert", test_tree_insert);
332 return g_test_run();