From e409b5ae5eb3b6cdfc7c85a2a587363eccccc8d1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 26 Nov 2001 19:08:46 +0000 Subject: [PATCH] Implement G_LEVEL_ORDER correctly. * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/tmpl/trees-nary.sgml: Document G_LEVEL_ORDER better. --- ChangeLog | 4 + ChangeLog.pre-2-0 | 4 + ChangeLog.pre-2-10 | 4 + ChangeLog.pre-2-12 | 4 + ChangeLog.pre-2-2 | 4 + ChangeLog.pre-2-4 | 4 + ChangeLog.pre-2-6 | 4 + ChangeLog.pre-2-8 | 4 + docs/reference/ChangeLog | 4 + docs/reference/glib/tmpl/trees-nary.sgml | 17 +-- glib/gnode.c | 132 +++++++---------------- tests/node-test.c | 11 +- 12 files changed, 89 insertions(+), 107 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 1a3557f37..b7ad0a362 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,4 +1,8 @@ 2001-11-26 Matthias Clasen + + * glib/gnode.c (g_node_traverse): Implement G_LEVEL_ORDER correctly. + + * tests/node-test.c: Add a testcase for G_LEVEL_ORDER implementation. * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343) diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index d5dc40743..6886f1ef8 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2001-11-26 Matthias Clasen + + * glib/tmpl/trees-nary.sgml: Document G_LEVEL_ORDER better. + 2001-11-22 Matthias Clasen Fixes for #61284: diff --git a/docs/reference/glib/tmpl/trees-nary.sgml b/docs/reference/glib/tmpl/trees-nary.sgml index dabd521f1..647ae0b27 100644 --- a/docs/reference/glib/tmpl/trees-nary.sgml +++ b/docs/reference/glib/tmpl/trees-nary.sgml @@ -222,22 +222,11 @@ and its children are visited. And so on. Specifies which nodes are visited during several of the tree functions, including g_node_traverse() and g_node_find(). - - -%G_TRAVERSE_LEAFS specifies that only leaf nodes should be visited. - - -%G_TRAVERSE_NON_LEAFS specifies that only non-leaf nodes should be visited. - - -%G_TRAVERSE_ALL specifies that all nodes should be visited. - - -@G_TRAVERSE_LEAFS: -@G_TRAVERSE_NON_LEAFS: -@G_TRAVERSE_ALL: +@G_TRAVERSE_LEAFS: only leaf nodes should be visited. +@G_TRAVERSE_NON_LEAFS: only non-leaf nodes should be visited. +@G_TRAVERSE_ALL: all nodes should be visited. @G_TRAVERSE_MASK: diff --git a/glib/gnode.c b/glib/gnode.c index 77143a8c4..a6888fe1c 100644 --- a/glib/gnode.c +++ b/glib/gnode.c @@ -671,97 +671,61 @@ g_node_depth_traverse_in_order (GNode *node, } static gboolean -g_node_traverse_children (GNode *node, - GTraverseFlags flags, - GNodeTraverseFunc func, - gpointer data) +g_node_traverse_level (GNode *node, + GTraverseFlags flags, + guint level, + GNodeTraverseFunc func, + gpointer data, + gboolean *more_levels) { - GNode *child; - - child = node->children; - - while (child) + if (level == 0) { - register GNode *current; - - current = child; - child = current->next; - - if (current->children) + if (node->children) { - if ((flags & G_TRAVERSE_NON_LEAFS) && - func (current, data)) - return TRUE; + *more_levels = TRUE; + return (flags & G_TRAVERSE_NON_LEAFS) && func (node, data); + } + else + { + return (flags & G_TRAVERSE_LEAFS) && func (node, data); } - else if ((flags & G_TRAVERSE_LEAFS) && - func (current, data)) - return TRUE; } - - child = node->children; - - while (child) + else { - register GNode *current; + node = node->children; - current = child; - child = current->next; - - if (current->children && - g_node_traverse_children (current, flags, func, data)) - return TRUE; + while (node) + { + if (g_node_traverse_level (node, flags, level - 1, func, data, more_levels)) + return TRUE; + + node = node->next; + } } - + return FALSE; } static gboolean -g_node_depth_traverse_children (GNode *node, - GTraverseFlags flags, - guint depth, - GNodeTraverseFunc func, - gpointer data) +g_node_depth_traverse_level (GNode *node, + GTraverseFlags flags, + guint depth, + GNodeTraverseFunc func, + gpointer data) { - GNode *child; - - child = node->children; - - while (child) + gint level; + gboolean more_levels; + + level = 0; + while (level != depth) { - register GNode *current; - - current = child; - child = current->next; - - if (current->children) - { - if ((flags & G_TRAVERSE_NON_LEAFS) && - func (current, data)) - return TRUE; - } - else if ((flags & G_TRAVERSE_LEAFS) && - func (current, data)) + more_levels = FALSE; + if (g_node_traverse_level (node, flags, level, func, data, &more_levels)) return TRUE; + if (!more_levels) + break; + level++; } - - depth--; - if (!depth) - return FALSE; - - child = node->children; - - while (child) - { - register GNode *current; - - current = child; - child = current->next; - - if (current->children && - g_node_depth_traverse_children (current, flags, depth, func, data)) - return TRUE; - } - return FALSE; } @@ -800,23 +764,7 @@ g_node_traverse (GNode *root, g_node_depth_traverse_in_order (root, flags, depth, func, data); break; case G_LEVEL_ORDER: - if (root->children) - { - if (!((flags & G_TRAVERSE_NON_LEAFS) && - func (root, data))) - { - if (depth < 0) - g_node_traverse_children (root, flags, func, data); - else - { - depth--; - if (depth) - g_node_depth_traverse_children (root, flags, depth, func, data); - } - } - } - else if (flags & G_TRAVERSE_LEAFS) - func (root, data); + g_node_depth_traverse_level (root, flags, depth, func, data); break; } } diff --git a/tests/node-test.c b/tests/node-test.c index 31b5db4db..8f5b54d81 100644 --- a/tests/node-test.c +++ b/tests/node-test.c @@ -88,6 +88,7 @@ g_node_test (void) GNode *root; GNode *node; GNode *node_B; + GNode *node_D; GNode *node_F; GNode *node_G; GNode *node_J; @@ -105,7 +106,8 @@ g_node_test (void) g_node_append_data (node_B, C2P ('E')); g_node_prepend_data (node_B, C2P ('C')); - g_node_insert (node_B, 1, g_node_new (C2P ('D'))); + node_D = g_node_new (C2P ('D')); + g_node_insert (node_B, 1, node_D); node_F = g_node_new (C2P ('F')); g_node_append (root, node_F); @@ -180,6 +182,13 @@ g_node_test (void) TEST (tstring, strcmp (tstring, "ABFEDCGKJIH") == 0); g_free (tstring); tstring = NULL; + g_node_append (node_D, g_node_new (C2P ('L'))); + g_node_append (node_D, g_node_new (C2P ('M'))); + + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); + TEST (tstring, strcmp (tstring, "ABFEDCGLMKJIH") == 0); + g_free (tstring); tstring = NULL; + g_node_destroy (root); /* allocation tests */