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.
This commit is contained in:
Matthias Clasen 2001-11-26 19:08:46 +00:00
parent e446298113
commit e409b5ae5e
12 changed files with 89 additions and 107 deletions

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,4 +1,8 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de> 2001-11-26 Matthias Clasen <matthiasc@poet.de>
* 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) * glib/gtree.h: Mark g_tree_traverse() as deprecated. (#65343)

View File

@ -1,3 +1,7 @@
2001-11-26 Matthias Clasen <matthiasc@poet.de>
* glib/tmpl/trees-nary.sgml: Document G_LEVEL_ORDER better.
2001-11-22 Matthias Clasen <matthiasc@poet.de> 2001-11-22 Matthias Clasen <matthiasc@poet.de>
Fixes for #61284: Fixes for #61284:

View File

@ -222,22 +222,11 @@ and its children are visited. And so on.
<para> <para>
Specifies which nodes are visited during several of the tree functions, Specifies which nodes are visited during several of the tree functions,
including g_node_traverse() and g_node_find(). including g_node_traverse() and g_node_find().
<itemizedlist>
<listitem><para>
%G_TRAVERSE_LEAFS specifies that only leaf nodes should be visited.
</para></listitem>
<listitem><para>
%G_TRAVERSE_NON_LEAFS specifies that only non-leaf nodes should be visited.
</para></listitem>
<listitem><para>
%G_TRAVERSE_ALL specifies that all nodes should be visited.
</para></listitem>
</itemizedlist>
</para> </para>
@G_TRAVERSE_LEAFS: @G_TRAVERSE_LEAFS: only leaf nodes should be visited.
@G_TRAVERSE_NON_LEAFS: @G_TRAVERSE_NON_LEAFS: only non-leaf nodes should be visited.
@G_TRAVERSE_ALL: @G_TRAVERSE_ALL: all nodes should be visited.
@G_TRAVERSE_MASK: @G_TRAVERSE_MASK:
<!-- ##### USER_FUNCTION GNodeTraverseFunc ##### --> <!-- ##### USER_FUNCTION GNodeTraverseFunc ##### -->

View File

@ -671,97 +671,61 @@ g_node_depth_traverse_in_order (GNode *node,
} }
static gboolean static gboolean
g_node_traverse_children (GNode *node, g_node_traverse_level (GNode *node,
GTraverseFlags flags, GTraverseFlags flags,
GNodeTraverseFunc func, guint level,
gpointer data) GNodeTraverseFunc func,
gpointer data,
gboolean *more_levels)
{ {
GNode *child; if (level == 0)
child = node->children;
while (child)
{ {
register GNode *current; if (node->children)
current = child;
child = current->next;
if (current->children)
{ {
if ((flags & G_TRAVERSE_NON_LEAFS) && *more_levels = TRUE;
func (current, data)) return (flags & G_TRAVERSE_NON_LEAFS) && func (node, data);
return TRUE; }
else
{
return (flags & G_TRAVERSE_LEAFS) && func (node, data);
} }
else if ((flags & G_TRAVERSE_LEAFS) &&
func (current, data))
return TRUE;
} }
else
child = node->children;
while (child)
{ {
register GNode *current; node = node->children;
current = child; while (node)
child = current->next; {
if (g_node_traverse_level (node, flags, level - 1, func, data, more_levels))
if (current->children && return TRUE;
g_node_traverse_children (current, flags, func, data))
return TRUE; node = node->next;
}
} }
return FALSE; return FALSE;
} }
static gboolean static gboolean
g_node_depth_traverse_children (GNode *node, g_node_depth_traverse_level (GNode *node,
GTraverseFlags flags, GTraverseFlags flags,
guint depth, guint depth,
GNodeTraverseFunc func, GNodeTraverseFunc func,
gpointer data) gpointer data)
{ {
GNode *child; gint level;
gboolean more_levels;
child = node->children;
level = 0;
while (child) while (level != depth)
{ {
register GNode *current; more_levels = FALSE;
if (g_node_traverse_level (node, flags, level, func, data, &more_levels))
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))
return TRUE; 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; return FALSE;
} }
@ -800,23 +764,7 @@ g_node_traverse (GNode *root,
g_node_depth_traverse_in_order (root, flags, depth, func, data); g_node_depth_traverse_in_order (root, flags, depth, func, data);
break; break;
case G_LEVEL_ORDER: case G_LEVEL_ORDER:
if (root->children) g_node_depth_traverse_level (root, flags, depth, func, data);
{
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);
break; break;
} }
} }

View File

@ -88,6 +88,7 @@ g_node_test (void)
GNode *root; GNode *root;
GNode *node; GNode *node;
GNode *node_B; GNode *node_B;
GNode *node_D;
GNode *node_F; GNode *node_F;
GNode *node_G; GNode *node_G;
GNode *node_J; GNode *node_J;
@ -105,7 +106,8 @@ g_node_test (void)
g_node_append_data (node_B, C2P ('E')); g_node_append_data (node_B, C2P ('E'));
g_node_prepend_data (node_B, C2P ('C')); 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')); node_F = g_node_new (C2P ('F'));
g_node_append (root, node_F); g_node_append (root, node_F);
@ -180,6 +182,13 @@ g_node_test (void)
TEST (tstring, strcmp (tstring, "ABFEDCGKJIH") == 0); TEST (tstring, strcmp (tstring, "ABFEDCGKJIH") == 0);
g_free (tstring); tstring = NULL; 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); g_node_destroy (root);
/* allocation tests */ /* allocation tests */