Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : /*
21 : : * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 : : * file for a list of people on the GLib Team. See the ChangeLog
23 : : * files for a list of changes. These files are distributed with
24 : : * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 : : */
26 : :
27 : : #undef G_DISABLE_ASSERT
28 : : #undef G_LOG_DOMAIN
29 : :
30 : : #include <stdio.h>
31 : : #include <string.h>
32 : : #include <stdlib.h>
33 : :
34 : : #include "glib.h"
35 : :
36 : : typedef struct {
37 : : GString *s;
38 : : gint count;
39 : : } CallbackData;
40 : :
41 : : static gboolean
42 : 509 : node_build_string (GNode *node,
43 : : gpointer data)
44 : : {
45 : 509 : CallbackData *d = data;
46 : :
47 [ + - ]: 509 : g_string_append_c (d->s, GPOINTER_TO_INT (node->data));
48 : :
49 : 509 : d->count--;
50 : :
51 [ + + ]: 509 : if (d->count == 0)
52 : 68 : return TRUE;
53 : :
54 : 441 : return FALSE;
55 : : }
56 : :
57 : : typedef struct {
58 : : GTraverseType traverse;
59 : : GTraverseFlags flags;
60 : : gint depth;
61 : : gint limit;
62 : : const gchar *expected;
63 : : } TraverseData;
64 : :
65 : : static void
66 : 1 : traversal_test (void)
67 : : {
68 : : GNode *root;
69 : : GNode *node_B;
70 : : GNode *node_C;
71 : : GNode *node_D;
72 : : GNode *node_E;
73 : : GNode *node_F;
74 : : GNode *node_G;
75 : : GNode *node_J;
76 : : GNode *n;
77 : 1 : TraverseData orders[] = {
78 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, -1, "ABCDEFGHIJK" },
79 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 1, -1, "A" },
80 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 2, -1, "ABF" },
81 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, -1, "ABCDEFG" },
82 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, -1, "ABCDEFG" },
83 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, -1, "CDEBHIJKGFA" },
84 : : { G_POST_ORDER, G_TRAVERSE_ALL, 1, -1, "A" },
85 : : { G_POST_ORDER, G_TRAVERSE_ALL, 2, -1, "BFA" },
86 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, -1, "CDEBGFA" },
87 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, -1, "CBDEAHGIJKF" },
88 : : { G_IN_ORDER, G_TRAVERSE_ALL, 1, -1, "A" },
89 : : { G_IN_ORDER, G_TRAVERSE_ALL, 2, -1, "BAF" },
90 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, -1, "CBDEAGF" },
91 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, -1, "ABFCDEGHIJK" },
92 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 1, -1, "A" },
93 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 2, -1, "ABF" },
94 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, -1, "ABFCDEG" },
95 : : { G_LEVEL_ORDER, G_TRAVERSE_LEAFS, -1, -1, "CDEHIJK" },
96 : : { G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, -1, -1, "ABFG" },
97 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 1, "A" },
98 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 2, "AB" },
99 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 3, "ABC" },
100 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 4, "ABCD" },
101 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 5, "ABCDE" },
102 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 6, "ABCDEF" },
103 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 7, "ABCDEFG" },
104 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 8, "ABCDEFGH" },
105 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 9, "ABCDEFGHI" },
106 : : { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 10, "ABCDEFGHIJ" },
107 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 1, "A" },
108 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 2, "AB" },
109 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 3, "ABC" },
110 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 4, "ABCD" },
111 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 5, "ABCDE" },
112 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 6, "ABCDEF" },
113 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 7, "ABCDEFG" },
114 : : { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 8, "ABCDEFG" },
115 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 1, "C" },
116 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 2, "CD" },
117 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 3, "CDE" },
118 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 4, "CDEB" },
119 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 5, "CDEBH" },
120 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 6, "CDEBHI" },
121 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 7, "CDEBHIJ" },
122 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 8, "CDEBHIJK" },
123 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 9, "CDEBHIJKG" },
124 : : { G_POST_ORDER, G_TRAVERSE_ALL, -1, 10, "CDEBHIJKGF" },
125 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 1, "C" },
126 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 2, "CD" },
127 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 3, "CDE" },
128 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 4, "CDEB" },
129 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 5, "CDEBG" },
130 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 6, "CDEBGF" },
131 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 7, "CDEBGFA" },
132 : : { G_POST_ORDER, G_TRAVERSE_ALL, 3, 8, "CDEBGFA" },
133 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 1, "C" },
134 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 2, "CB" },
135 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 3, "CBD" },
136 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 4, "CBDE" },
137 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 5, "CBDEA" },
138 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 6, "CBDEAH" },
139 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 7, "CBDEAHG" },
140 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 8, "CBDEAHGI" },
141 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 9, "CBDEAHGIJ" },
142 : : { G_IN_ORDER, G_TRAVERSE_ALL, -1, 10, "CBDEAHGIJK" },
143 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 1, "C" },
144 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 2, "CB" },
145 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 3, "CBD" },
146 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 4, "CBDE" },
147 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 5, "CBDEA" },
148 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 6, "CBDEAG" },
149 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 7, "CBDEAGF" },
150 : : { G_IN_ORDER, G_TRAVERSE_ALL, 3, 8, "CBDEAGF" },
151 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 1, "A" },
152 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 2, "AB" },
153 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 3, "ABF" },
154 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 4, "ABFC" },
155 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 5, "ABFCD" },
156 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 6, "ABFCDE" },
157 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 7, "ABFCDEG" },
158 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 8, "ABFCDEGH" },
159 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 9, "ABFCDEGHI" },
160 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 10, "ABFCDEGHIJ" },
161 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 1, "A" },
162 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 2, "AB" },
163 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 3, "ABF" },
164 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 4, "ABFC" },
165 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 5, "ABFCD" },
166 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 6, "ABFCDE" },
167 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 7, "ABFCDEG" },
168 : : { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 8, "ABFCDEG" },
169 : : };
170 : : gsize i;
171 : : CallbackData data;
172 : :
173 : 1 : root = g_node_new (GINT_TO_POINTER ('A'));
174 : 1 : node_B = g_node_new (GINT_TO_POINTER ('B'));
175 : 1 : g_node_append (root, node_B);
176 : 1 : g_node_append_data (node_B, GINT_TO_POINTER ('E'));
177 : 1 : g_node_prepend_data (node_B, GINT_TO_POINTER ('C'));
178 : 1 : node_D = g_node_new (GINT_TO_POINTER ('D'));
179 : 1 : g_node_insert (node_B, 1, node_D);
180 : 1 : node_F = g_node_new (GINT_TO_POINTER ('F'));
181 : 1 : g_node_append (root, node_F);
182 : 1 : node_G = g_node_new (GINT_TO_POINTER ('G'));
183 : 1 : g_node_append (node_F, node_G);
184 : 1 : node_J = g_node_new (GINT_TO_POINTER ('J'));
185 : 1 : g_node_prepend (node_G, node_J);
186 : 1 : g_node_insert (node_G, 42, g_node_new (GINT_TO_POINTER ('K')));
187 : 1 : g_node_insert_data (node_G, 0, GINT_TO_POINTER ('H'));
188 : 1 : g_node_insert (node_G, 1, g_node_new (GINT_TO_POINTER ('I')));
189 : :
190 : : /* we have built: A
191 : : * / \
192 : : * B F
193 : : * / | \ \
194 : : * C D E G
195 : : * / /\ \
196 : : * H I J K
197 : : *
198 : : * for in-order traversal, 'G' is considered to be the "left"
199 : : * child of 'F', which will cause 'F' to be the last node visited.
200 : : */
201 : :
202 : 1 : node_C = node_B->children;
203 : 1 : node_E = node_D->next;
204 : :
205 : 1 : n = g_node_last_sibling (node_C);
206 : 1 : g_assert (n == node_E);
207 : 1 : n = g_node_last_sibling (node_D);
208 : 1 : g_assert (n == node_E);
209 : 1 : n = g_node_last_sibling (node_E);
210 : 1 : g_assert (n == node_E);
211 : :
212 : 1 : data.s = g_string_new ("");
213 [ + + ]: 92 : for (i = 0; i < G_N_ELEMENTS (orders); i++)
214 : : {
215 : 91 : g_string_set_size (data.s, 0);
216 : 91 : data.count = orders[i].limit;
217 : 91 : g_node_traverse (root, orders[i].traverse, orders[i].flags, orders[i].depth, node_build_string, &data);
218 : 91 : g_assert_cmpstr (data.s->str, ==, orders[i].expected);
219 : : }
220 : :
221 : 1 : g_node_reverse_children (node_B);
222 : 1 : g_node_reverse_children (node_G);
223 : :
224 : 1 : g_string_set_size (data.s, 0);
225 : 1 : data.count = -1;
226 : 1 : g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data);
227 : 1 : g_assert_cmpstr (data.s->str, ==, "ABFEDCGKJIH");
228 : :
229 : 1 : g_node_append (node_D, g_node_new (GINT_TO_POINTER ('L')));
230 : 1 : g_node_insert (node_D, -1, g_node_new (GINT_TO_POINTER ('M')));
231 : :
232 : 1 : g_string_set_size (data.s, 0);
233 : 1 : data.count = -1;
234 : 1 : g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data);
235 : 1 : g_assert_cmpstr (data.s->str, ==, "ABFEDCGLMKJIH");
236 : :
237 : 1 : g_string_set_size (data.s, 0);
238 : 1 : data.count = -1;
239 : 1 : g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1, node_build_string, &data);
240 : 1 : g_assert_cmpstr (data.s->str, ==, "ELMCKJIH");
241 : :
242 : 1 : g_string_set_size (data.s, 0);
243 : 1 : data.count = -1;
244 : 1 : g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_NON_LEAFS, -1, node_build_string, &data);
245 : 1 : g_assert_cmpstr (data.s->str, ==, "ABDFG");
246 : :
247 : 1 : g_node_destroy (root);
248 : 1 : g_string_free (data.s, TRUE);
249 : 1 : }
250 : :
251 : : static void
252 : 1 : construct_test (void)
253 : : {
254 : : GNode *root;
255 : : GNode *node;
256 : : GNode *node_B;
257 : : GNode *node_D;
258 : : GNode *node_F;
259 : : GNode *node_G;
260 : : GNode *node_J;
261 : : GNode *node_H;
262 : : guint i;
263 : :
264 : 1 : root = g_node_new (GINT_TO_POINTER ('A'));
265 : 1 : g_assert_cmpint (g_node_depth (root), ==, 1);
266 : 1 : g_assert_cmpint (g_node_max_height (root), ==, 1);
267 : :
268 : 1 : node_B = g_node_new (GINT_TO_POINTER ('B'));
269 : 1 : g_node_append (root, node_B);
270 : 1 : g_assert (root->children == node_B);
271 : :
272 : 1 : g_node_append_data (node_B, GINT_TO_POINTER ('E'));
273 : 1 : g_node_prepend_data (node_B, GINT_TO_POINTER ('C'));
274 : 1 : node_D = g_node_new (GINT_TO_POINTER ('D'));
275 : 1 : g_node_insert (node_B, 1, node_D);
276 : :
277 : 1 : node_F = g_node_new (GINT_TO_POINTER ('F'));
278 : 1 : g_node_append (root, node_F);
279 : 1 : g_assert (root->children->next == node_F);
280 : :
281 : 1 : node_G = g_node_new (GINT_TO_POINTER ('G'));
282 : 1 : g_node_append (node_F, node_G);
283 : 1 : node_J = g_node_new (GINT_TO_POINTER ('J'));
284 : 1 : g_node_insert_after (node_G, NULL, node_J);
285 : 1 : g_node_insert (node_G, 42, g_node_new (GINT_TO_POINTER ('K')));
286 : 1 : node_H = g_node_new (GINT_TO_POINTER ('H'));
287 : 1 : g_node_insert_after (node_G, NULL, node_H);
288 : 1 : g_node_insert (node_G, 1, g_node_new (GINT_TO_POINTER ('I')));
289 : :
290 : : /* we have built: A
291 : : * / \
292 : : * B F
293 : : * / | \ \
294 : : * C D E G
295 : : * / /\ \
296 : : * H I J K
297 : : */
298 : 1 : g_assert_cmpint (g_node_depth (root), ==, 1);
299 : 1 : g_assert_cmpint (g_node_max_height (root), ==, 4);
300 : 1 : g_assert_cmpint (g_node_depth (node_G->children->next), ==, 4);
301 : 1 : g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_LEAFS), ==, 7);
302 : 1 : g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_NON_LEAFS), ==, 4);
303 : 1 : g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_ALL), ==, 11);
304 : 1 : g_assert_cmpint (g_node_max_height (node_F), ==, 3);
305 : 1 : g_assert_cmpint (g_node_n_children (node_G), ==, 4);
306 : 1 : g_assert (g_node_find_child (root, G_TRAVERSE_ALL, GINT_TO_POINTER ('F')) == node_F);
307 : 1 : g_assert (g_node_find_child (node_G, G_TRAVERSE_LEAFS, GINT_TO_POINTER ('H')) == node_H);
308 : 1 : g_assert (g_node_find_child (root, G_TRAVERSE_ALL, GINT_TO_POINTER ('H')) == NULL);
309 : 1 : g_assert (g_node_find (root, G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, GINT_TO_POINTER ('I')) == NULL);
310 : 1 : g_assert (g_node_find (root, G_IN_ORDER, G_TRAVERSE_LEAFS, GINT_TO_POINTER ('J')) == node_J);
311 : :
312 [ + + ]: 4 : for (i = 0; i < g_node_n_children (node_B); i++)
313 : : {
314 : 3 : node = g_node_nth_child (node_B, i);
315 : 3 : g_assert_cmpint (GPOINTER_TO_INT (node->data), ==, ('C' + i));
316 : : }
317 : :
318 [ + + ]: 5 : for (i = 0; i < g_node_n_children (node_G); i++)
319 : 4 : g_assert_cmpint (g_node_child_position (node_G, g_node_nth_child (node_G, i)), ==, i);
320 : :
321 : 1 : g_node_destroy (root);
322 : 1 : }
323 : :
324 : : static void
325 : 1 : allocation_test (void)
326 : : {
327 : : GNode *root;
328 : : GNode *node;
329 : : gint i;
330 : :
331 : 1 : root = g_node_new (NULL);
332 : 1 : node = root;
333 : :
334 [ + + ]: 2049 : for (i = 0; i < 2048; i++)
335 : : {
336 : 2048 : g_node_append (node, g_node_new (NULL));
337 [ + + ]: 2048 : if ((i % 5) == 4)
338 : 409 : node = node->children->next;
339 : : }
340 : 1 : g_assert_cmpint (g_node_max_height (root), >, 100);
341 : 1 : g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_ALL), ==, 1 + 2048);
342 : :
343 : 1 : g_node_destroy (root);
344 : 1 : }
345 : :
346 : :
347 : : static void
348 : 1 : misc_test (void)
349 : : {
350 : : GNode *root;
351 : : GNode *node_B;
352 : : GNode *node_C;
353 : : GNode *node_D;
354 : : GNode *node_E;
355 : : CallbackData data;
356 : :
357 : 1 : root = g_node_new (GINT_TO_POINTER ('A'));
358 : 1 : node_B = g_node_new (GINT_TO_POINTER ('B'));
359 : 1 : g_node_append (root, node_B);
360 : 1 : node_D = g_node_new (GINT_TO_POINTER ('D'));
361 : 1 : g_node_append (root, node_D);
362 : 1 : node_C = g_node_new (GINT_TO_POINTER ('C'));
363 : 1 : g_node_insert_after (root, node_B, node_C);
364 : 1 : node_E = g_node_new (GINT_TO_POINTER ('E'));
365 : 1 : g_node_append (node_C, node_E);
366 : :
367 : 1 : g_assert (g_node_get_root (node_E) == root);
368 : 1 : g_assert (g_node_is_ancestor (root, node_B));
369 : 1 : g_assert (g_node_is_ancestor (root, node_E));
370 : 1 : g_assert (!g_node_is_ancestor (node_B, node_D));
371 : 1 : g_assert (g_node_first_sibling (node_D) == node_B);
372 : 1 : g_assert (g_node_first_sibling (node_E) == node_E);
373 : 1 : g_assert (g_node_first_sibling (root) == root);
374 : 1 : g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('B')), ==, 0);
375 : 1 : g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('C')), ==, 1);
376 : 1 : g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('D')), ==, 2);
377 : 1 : g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('E')), ==, -1);
378 : :
379 : 1 : data.s = g_string_new ("");
380 : 1 : data.count = -1;
381 : 1 : g_node_children_foreach (root, G_TRAVERSE_ALL, (GNodeForeachFunc)node_build_string, &data);
382 : 1 : g_assert_cmpstr (data.s->str, ==, "BCD");
383 : :
384 : 1 : g_string_set_size (data.s, 0);
385 : 1 : data.count = -1;
386 : 1 : g_node_children_foreach (root, G_TRAVERSE_LEAVES, (GNodeForeachFunc)node_build_string, &data);
387 : 1 : g_assert_cmpstr (data.s->str, ==, "BD");
388 : :
389 : 1 : g_string_set_size (data.s, 0);
390 : 1 : data.count = -1;
391 : 1 : g_node_children_foreach (root, G_TRAVERSE_NON_LEAVES, (GNodeForeachFunc)node_build_string, &data);
392 : 1 : g_assert_cmpstr (data.s->str, ==, "C");
393 : 1 : g_string_free (data.s, TRUE);
394 : :
395 : 1 : g_node_destroy (root);
396 : 1 : }
397 : :
398 : : static gboolean
399 : 31 : check_order (GNode *node,
400 : : gpointer data)
401 : : {
402 : 31 : gchar **expected = data;
403 : : gchar d;
404 : :
405 : 31 : d = GPOINTER_TO_INT (node->data);
406 : 31 : g_assert_cmpint (d, ==, **expected);
407 : 31 : (*expected)++;
408 : :
409 : 31 : return FALSE;
410 : : }
411 : :
412 : : static void
413 : 1 : unlink_test (void)
414 : : {
415 : : GNode *root;
416 : : GNode *node;
417 : : GNode *bnode;
418 : : GNode *cnode;
419 : : gchar *expected;
420 : :
421 : : /*
422 : : * -------- a --------
423 : : * / | \
424 : : * b c d
425 : : * / | \ / | \ / | \
426 : : * e f g h i j k l m
427 : : *
428 : : */
429 : :
430 : 1 : root = g_node_new (GINT_TO_POINTER ('a'));
431 : 1 : node = bnode = g_node_append_data (root, GINT_TO_POINTER ('b'));
432 : 1 : g_node_append_data (node, GINT_TO_POINTER ('e'));
433 : 1 : g_node_append_data (node, GINT_TO_POINTER ('f'));
434 : 1 : g_node_append_data (node, GINT_TO_POINTER ('g'));
435 : :
436 : 1 : node = cnode = g_node_append_data (root, GINT_TO_POINTER ('c'));
437 : 1 : g_node_append_data (node, GINT_TO_POINTER ('h'));
438 : 1 : g_node_append_data (node, GINT_TO_POINTER ('i'));
439 : 1 : g_node_append_data (node, GINT_TO_POINTER ('j'));
440 : :
441 : 1 : node = g_node_append_data (root, GINT_TO_POINTER ('d'));
442 : 1 : g_node_append_data (node, GINT_TO_POINTER ('k'));
443 : 1 : g_node_append_data (node, GINT_TO_POINTER ('l'));
444 : 1 : g_node_append_data (node, GINT_TO_POINTER ('m'));
445 : :
446 : 1 : g_node_unlink (cnode);
447 : :
448 : 1 : expected = "abdefgklm";
449 : 1 : g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
450 : :
451 : 1 : expected = "abd";
452 : 1 : g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, 1, check_order, &expected);
453 : :
454 : 1 : expected = "chij";
455 : 1 : g_node_traverse (cnode, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
456 : :
457 : 1 : g_node_destroy (bnode);
458 : :
459 : 1 : expected = "adklm";
460 : 1 : g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
461 : :
462 : 1 : g_node_destroy (root);
463 : 1 : g_node_destroy (cnode);
464 : 1 : }
465 : :
466 : : static gpointer
467 : 4 : copy_up (gconstpointer src,
468 : : gpointer data)
469 : : {
470 : : gchar l, u;
471 : :
472 : 4 : l = GPOINTER_TO_INT (src);
473 : 4 : u = g_ascii_toupper (l);
474 : :
475 : 4 : return GINT_TO_POINTER ((int)u);
476 : : }
477 : :
478 : : static void
479 : 1 : copy_test (void)
480 : : {
481 : : GNode *root;
482 : : GNode *copy;
483 : : gchar *expected;
484 : :
485 : 1 : root = g_node_new (GINT_TO_POINTER ('a'));
486 : 1 : g_node_append_data (root, GINT_TO_POINTER ('b'));
487 : 1 : g_node_append_data (root, GINT_TO_POINTER ('c'));
488 : 1 : g_node_append_data (root, GINT_TO_POINTER ('d'));
489 : :
490 : 1 : expected = "abcd";
491 : 1 : g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
492 : :
493 : 1 : copy = g_node_copy (root);
494 : :
495 : 1 : expected = "abcd";
496 : 1 : g_node_traverse (copy, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
497 : :
498 : 1 : g_node_destroy (copy);
499 : :
500 : 1 : copy = g_node_copy_deep (root, copy_up, NULL);
501 : :
502 : 1 : expected = "ABCD";
503 : 1 : g_node_traverse (copy, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
504 : :
505 : 1 : g_node_destroy (copy);
506 : :
507 : 1 : g_node_destroy (root);
508 : 1 : }
509 : :
510 : : int
511 : 1 : main (int argc,
512 : : char *argv[])
513 : : {
514 : 1 : g_test_init (&argc, &argv, NULL);
515 : :
516 : 1 : g_test_add_func ("/node/allocation", allocation_test);
517 : 1 : g_test_add_func ("/node/construction", construct_test);
518 : 1 : g_test_add_func ("/node/traversal", traversal_test);
519 : 1 : g_test_add_func ("/node/misc", misc_test);
520 : 1 : g_test_add_func ("/node/unlink", unlink_test);
521 : 1 : g_test_add_func ("/node/copy", copy_test);
522 : :
523 : 1 : return g_test_run ();
524 : : }
|