Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / glib / gnode.c
blob5145c6bd65b1870e017a16e382f3a41ea64d856b
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * GNode: N-way tree implementation.
5 * Copyright (C) 1998 Tim Janik
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GLib Team and others 1997-1999. See the AUTHORS
25 * file for a list of people on the GLib Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GLib at ftp://ftp.gtk.org/pub/gtk/.
30 /*
31 * MT safe
34 #include "glib.h"
36 /* node allocation
38 struct _GAllocator /* from gmem.c */
40 gchar *name;
41 guint16 n_preallocs;
42 guint is_unused : 1;
43 guint type : 4;
44 GAllocator *last;
45 GMemChunk *mem_chunk;
46 GNode *free_nodes; /* implementation specific */
49 G_LOCK_DEFINE_STATIC (current_allocator);
50 static GAllocator *current_allocator = NULL;
52 /* HOLDS: current_allocator_lock */
53 static void
54 g_node_validate_allocator (GAllocator *allocator)
56 g_return_if_fail (allocator != NULL);
57 g_return_if_fail (allocator->is_unused == TRUE);
59 if (allocator->type != G_ALLOCATOR_NODE)
61 allocator->type = G_ALLOCATOR_NODE;
62 if (allocator->mem_chunk)
64 g_mem_chunk_destroy (allocator->mem_chunk);
65 allocator->mem_chunk = NULL;
69 if (!allocator->mem_chunk)
71 allocator->mem_chunk = g_mem_chunk_new (allocator->name,
72 sizeof (GNode),
73 sizeof (GNode) * allocator->n_preallocs,
74 G_ALLOC_ONLY);
75 allocator->free_nodes = NULL;
78 allocator->is_unused = FALSE;
81 void
82 g_node_push_allocator (GAllocator *allocator)
84 G_LOCK (current_allocator);
85 g_node_validate_allocator ( allocator );
86 allocator->last = current_allocator;
87 current_allocator = allocator;
88 G_UNLOCK (current_allocator);
91 void
92 g_node_pop_allocator (void)
94 G_LOCK (current_allocator);
95 if (current_allocator)
97 GAllocator *allocator;
99 allocator = current_allocator;
100 current_allocator = allocator->last;
101 allocator->last = NULL;
102 allocator->is_unused = TRUE;
104 G_UNLOCK (current_allocator);
108 /* --- functions --- */
109 GNode*
110 g_node_new (gpointer data)
112 GNode *node;
114 G_LOCK (current_allocator);
115 if (!current_allocator)
117 GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
118 128);
119 g_node_validate_allocator (allocator);
120 allocator->last = NULL;
121 current_allocator = allocator;
123 if (!current_allocator->free_nodes)
124 node = g_chunk_new (GNode, current_allocator->mem_chunk);
125 else
127 node = current_allocator->free_nodes;
128 current_allocator->free_nodes = node->next;
130 G_UNLOCK (current_allocator);
132 node->data = data;
133 node->next = NULL;
134 node->prev = NULL;
135 node->parent = NULL;
136 node->children = NULL;
138 return node;
141 static void
142 g_nodes_free (GNode *node)
144 GNode *parent;
146 parent = node;
147 while (1)
149 if (parent->children)
150 g_nodes_free (parent->children);
151 if (parent->next)
152 parent = parent->next;
153 else
154 break;
157 G_LOCK (current_allocator);
158 parent->next = current_allocator->free_nodes;
159 current_allocator->free_nodes = node;
160 G_UNLOCK (current_allocator);
163 void
164 g_node_destroy (GNode *root)
166 g_return_if_fail (root != NULL);
168 if (!G_NODE_IS_ROOT (root))
169 g_node_unlink (root);
171 g_nodes_free (root);
174 void
175 g_node_unlink (GNode *node)
177 g_return_if_fail (node != NULL);
179 if (node->prev)
180 node->prev->next = node->next;
181 else if (node->parent)
182 node->parent->children = node->next;
183 node->parent = NULL;
184 if (node->next)
186 node->next->prev = node->prev;
187 node->next = NULL;
189 node->prev = NULL;
192 GNode*
193 g_node_insert (GNode *parent,
194 gint position,
195 GNode *node)
197 g_return_val_if_fail (parent != NULL, node);
198 g_return_val_if_fail (node != NULL, node);
199 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
201 if (position > 0)
202 return g_node_insert_before (parent,
203 g_node_nth_child (parent, position),
204 node);
205 else if (position == 0)
206 return g_node_prepend (parent, node);
207 else /* if (position < 0) */
208 return g_node_append (parent, node);
211 GNode*
212 g_node_insert_before (GNode *parent,
213 GNode *sibling,
214 GNode *node)
216 g_return_val_if_fail (parent != NULL, node);
217 g_return_val_if_fail (node != NULL, node);
218 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
219 if (sibling)
220 g_return_val_if_fail (sibling->parent == parent, node);
222 node->parent = parent;
224 if (sibling)
226 if (sibling->prev)
228 node->prev = sibling->prev;
229 node->prev->next = node;
230 node->next = sibling;
231 sibling->prev = node;
233 else
235 node->parent->children = node;
236 node->next = sibling;
237 sibling->prev = node;
240 else
242 if (parent->children)
244 sibling = parent->children;
245 while (sibling->next)
246 sibling = sibling->next;
247 node->prev = sibling;
248 sibling->next = node;
250 else
251 node->parent->children = node;
254 return node;
257 GNode*
258 g_node_prepend (GNode *parent,
259 GNode *node)
261 g_return_val_if_fail (parent != NULL, node);
263 return g_node_insert_before (parent, parent->children, node);
266 GNode*
267 g_node_get_root (GNode *node)
269 g_return_val_if_fail (node != NULL, NULL);
271 while (node->parent)
272 node = node->parent;
274 return node;
277 gboolean
278 g_node_is_ancestor (GNode *node,
279 GNode *descendant)
281 g_return_val_if_fail (node != NULL, FALSE);
282 g_return_val_if_fail (descendant != NULL, FALSE);
284 while (descendant)
286 if (descendant->parent == node)
287 return TRUE;
289 descendant = descendant->parent;
292 return FALSE;
295 /* returns 1 for root, 2 for first level children,
296 * 3 for children's children...
298 guint
299 g_node_depth (GNode *node)
301 register guint depth = 0;
303 while (node)
305 depth++;
306 node = node->parent;
309 return depth;
312 void
313 g_node_reverse_children (GNode *node)
315 GNode *child;
316 GNode *last;
318 g_return_if_fail (node != NULL);
320 child = node->children;
321 last = NULL;
322 while (child)
324 last = child;
325 child = last->next;
326 last->next = last->prev;
327 last->prev = child;
329 node->children = last;
332 guint
333 g_node_max_height (GNode *root)
335 register GNode *child;
336 register guint max_height = 0;
338 if (!root)
339 return 0;
341 child = root->children;
342 while (child)
344 register guint tmp_height;
346 tmp_height = g_node_max_height (child);
347 if (tmp_height > max_height)
348 max_height = tmp_height;
349 child = child->next;
352 return max_height + 1;
355 static gboolean
356 g_node_traverse_pre_order (GNode *node,
357 GTraverseFlags flags,
358 GNodeTraverseFunc func,
359 gpointer data)
361 if (node->children)
363 GNode *child;
365 if ((flags & G_TRAVERSE_NON_LEAFS) &&
366 func (node, data))
367 return TRUE;
369 child = node->children;
370 while (child)
372 register GNode *current;
374 current = child;
375 child = current->next;
376 if (g_node_traverse_pre_order (current, flags, func, data))
377 return TRUE;
380 else if ((flags & G_TRAVERSE_LEAFS) &&
381 func (node, data))
382 return TRUE;
384 return FALSE;
387 static gboolean
388 g_node_depth_traverse_pre_order (GNode *node,
389 GTraverseFlags flags,
390 guint depth,
391 GNodeTraverseFunc func,
392 gpointer data)
394 if (node->children)
396 GNode *child;
398 if ((flags & G_TRAVERSE_NON_LEAFS) &&
399 func (node, data))
400 return TRUE;
402 depth--;
403 if (!depth)
404 return FALSE;
406 child = node->children;
407 while (child)
409 register GNode *current;
411 current = child;
412 child = current->next;
413 if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
414 return TRUE;
417 else if ((flags & G_TRAVERSE_LEAFS) &&
418 func (node, data))
419 return TRUE;
421 return FALSE;
424 static gboolean
425 g_node_traverse_post_order (GNode *node,
426 GTraverseFlags flags,
427 GNodeTraverseFunc func,
428 gpointer data)
430 if (node->children)
432 GNode *child;
434 child = node->children;
435 while (child)
437 register GNode *current;
439 current = child;
440 child = current->next;
441 if (g_node_traverse_post_order (current, flags, func, data))
442 return TRUE;
445 if ((flags & G_TRAVERSE_NON_LEAFS) &&
446 func (node, data))
447 return TRUE;
450 else if ((flags & G_TRAVERSE_LEAFS) &&
451 func (node, data))
452 return TRUE;
454 return FALSE;
457 static gboolean
458 g_node_depth_traverse_post_order (GNode *node,
459 GTraverseFlags flags,
460 guint depth,
461 GNodeTraverseFunc func,
462 gpointer data)
464 if (node->children)
466 depth--;
467 if (depth)
469 GNode *child;
471 child = node->children;
472 while (child)
474 register GNode *current;
476 current = child;
477 child = current->next;
478 if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
479 return TRUE;
483 if ((flags & G_TRAVERSE_NON_LEAFS) &&
484 func (node, data))
485 return TRUE;
488 else if ((flags & G_TRAVERSE_LEAFS) &&
489 func (node, data))
490 return TRUE;
492 return FALSE;
495 static gboolean
496 g_node_traverse_in_order (GNode *node,
497 GTraverseFlags flags,
498 GNodeTraverseFunc func,
499 gpointer data)
501 if (node->children)
503 GNode *child;
504 register GNode *current;
506 child = node->children;
507 current = child;
508 child = current->next;
510 if (g_node_traverse_in_order (current, flags, func, data))
511 return TRUE;
513 if ((flags & G_TRAVERSE_NON_LEAFS) &&
514 func (node, data))
515 return TRUE;
517 while (child)
519 current = child;
520 child = current->next;
521 if (g_node_traverse_in_order (current, flags, func, data))
522 return TRUE;
525 else if ((flags & G_TRAVERSE_LEAFS) &&
526 func (node, data))
527 return TRUE;
529 return FALSE;
532 static gboolean
533 g_node_depth_traverse_in_order (GNode *node,
534 GTraverseFlags flags,
535 guint depth,
536 GNodeTraverseFunc func,
537 gpointer data)
539 if (node->children)
541 depth--;
542 if (depth)
544 GNode *child;
545 register GNode *current;
547 child = node->children;
548 current = child;
549 child = current->next;
551 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
552 return TRUE;
554 if ((flags & G_TRAVERSE_NON_LEAFS) &&
555 func (node, data))
556 return TRUE;
558 while (child)
560 current = child;
561 child = current->next;
562 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
563 return TRUE;
566 else if ((flags & G_TRAVERSE_NON_LEAFS) &&
567 func (node, data))
568 return TRUE;
570 else if ((flags & G_TRAVERSE_LEAFS) &&
571 func (node, data))
572 return TRUE;
574 return FALSE;
577 static gboolean
578 g_node_traverse_children (GNode *node,
579 GTraverseFlags flags,
580 GNodeTraverseFunc func,
581 gpointer data)
583 GNode *child;
585 child = node->children;
587 while (child)
589 register GNode *current;
591 current = child;
592 child = current->next;
594 if (current->children)
596 if ((flags & G_TRAVERSE_NON_LEAFS) &&
597 func (current, data))
598 return TRUE;
600 else if ((flags & G_TRAVERSE_LEAFS) &&
601 func (current, data))
602 return TRUE;
605 child = node->children;
607 while (child)
609 register GNode *current;
611 current = child;
612 child = current->next;
614 if (current->children &&
615 g_node_traverse_children (current, flags, func, data))
616 return TRUE;
619 return FALSE;
622 static gboolean
623 g_node_depth_traverse_children (GNode *node,
624 GTraverseFlags flags,
625 guint depth,
626 GNodeTraverseFunc func,
627 gpointer data)
629 GNode *child;
631 child = node->children;
633 while (child)
635 register GNode *current;
637 current = child;
638 child = current->next;
640 if (current->children)
642 if ((flags & G_TRAVERSE_NON_LEAFS) &&
643 func (current, data))
644 return TRUE;
646 else if ((flags & G_TRAVERSE_LEAFS) &&
647 func (current, data))
648 return TRUE;
651 depth--;
652 if (!depth)
653 return FALSE;
655 child = node->children;
657 while (child)
659 register GNode *current;
661 current = child;
662 child = current->next;
664 if (current->children &&
665 g_node_depth_traverse_children (current, flags, depth, func, data))
666 return TRUE;
669 return FALSE;
672 void
673 g_node_traverse (GNode *root,
674 GTraverseType order,
675 GTraverseFlags flags,
676 gint depth,
677 GNodeTraverseFunc func,
678 gpointer data)
680 g_return_if_fail (root != NULL);
681 g_return_if_fail (func != NULL);
682 g_return_if_fail (order <= G_LEVEL_ORDER);
683 g_return_if_fail (flags <= G_TRAVERSE_MASK);
684 g_return_if_fail (depth == -1 || depth > 0);
686 switch (order)
688 case G_PRE_ORDER:
689 if (depth < 0)
690 g_node_traverse_pre_order (root, flags, func, data);
691 else
692 g_node_depth_traverse_pre_order (root, flags, depth, func, data);
693 break;
694 case G_POST_ORDER:
695 if (depth < 0)
696 g_node_traverse_post_order (root, flags, func, data);
697 else
698 g_node_depth_traverse_post_order (root, flags, depth, func, data);
699 break;
700 case G_IN_ORDER:
701 if (depth < 0)
702 g_node_traverse_in_order (root, flags, func, data);
703 else
704 g_node_depth_traverse_in_order (root, flags, depth, func, data);
705 break;
706 case G_LEVEL_ORDER:
707 if (root->children)
709 if (!((flags & G_TRAVERSE_NON_LEAFS) &&
710 func (root, data)))
712 if (depth < 0)
713 g_node_traverse_children (root, flags, func, data);
714 else
716 depth--;
717 if (depth)
718 g_node_depth_traverse_children (root, flags, depth, func, data);
722 else if (flags & G_TRAVERSE_LEAFS)
723 func (root, data);
724 break;
728 static gboolean
729 g_node_find_func (GNode *node,
730 gpointer data)
732 register gpointer *d = data;
734 if (*d != node->data)
735 return FALSE;
737 *(++d) = node;
739 return TRUE;
742 GNode*
743 g_node_find (GNode *root,
744 GTraverseType order,
745 GTraverseFlags flags,
746 gpointer data)
748 gpointer d[2];
750 g_return_val_if_fail (root != NULL, NULL);
751 g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
752 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
754 d[0] = data;
755 d[1] = NULL;
757 g_node_traverse (root, order, flags, -1, g_node_find_func, d);
759 return d[1];
762 static void
763 g_node_count_func (GNode *node,
764 GTraverseFlags flags,
765 guint *n)
767 if (node->children)
769 GNode *child;
771 if (flags & G_TRAVERSE_NON_LEAFS)
772 (*n)++;
774 child = node->children;
775 while (child)
777 g_node_count_func (child, flags, n);
778 child = child->next;
781 else if (flags & G_TRAVERSE_LEAFS)
782 (*n)++;
785 guint
786 g_node_n_nodes (GNode *root,
787 GTraverseFlags flags)
789 guint n = 0;
791 g_return_val_if_fail (root != NULL, 0);
792 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
794 g_node_count_func (root, flags, &n);
796 return n;
799 GNode*
800 g_node_last_child (GNode *node)
802 g_return_val_if_fail (node != NULL, NULL);
804 node = node->children;
805 if (node)
806 while (node->next)
807 node = node->next;
809 return node;
812 GNode*
813 g_node_nth_child (GNode *node,
814 guint n)
816 g_return_val_if_fail (node != NULL, NULL);
818 node = node->children;
819 if (node)
820 while ((n-- > 0) && node)
821 node = node->next;
823 return node;
826 guint
827 g_node_n_children (GNode *node)
829 guint n = 0;
831 g_return_val_if_fail (node != NULL, 0);
833 node = node->children;
834 while (node)
836 n++;
837 node = node->next;
840 return n;
843 GNode*
844 g_node_find_child (GNode *node,
845 GTraverseFlags flags,
846 gpointer data)
848 g_return_val_if_fail (node != NULL, NULL);
849 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
851 node = node->children;
852 while (node)
854 if (node->data == data)
856 if (G_NODE_IS_LEAF (node))
858 if (flags & G_TRAVERSE_LEAFS)
859 return node;
861 else
863 if (flags & G_TRAVERSE_NON_LEAFS)
864 return node;
867 node = node->next;
870 return NULL;
873 gint
874 g_node_child_position (GNode *node,
875 GNode *child)
877 register guint n = 0;
879 g_return_val_if_fail (node != NULL, -1);
880 g_return_val_if_fail (child != NULL, -1);
881 g_return_val_if_fail (child->parent == node, -1);
883 node = node->children;
884 while (node)
886 if (node == child)
887 return n;
888 n++;
889 node = node->next;
892 return -1;
895 gint
896 g_node_child_index (GNode *node,
897 gpointer data)
899 register guint n = 0;
901 g_return_val_if_fail (node != NULL, -1);
903 node = node->children;
904 while (node)
906 if (node->data == data)
907 return n;
908 n++;
909 node = node->next;
912 return -1;
915 GNode*
916 g_node_first_sibling (GNode *node)
918 g_return_val_if_fail (node != NULL, NULL);
920 while (node->prev)
921 node = node->prev;
923 return node;
926 GNode*
927 g_node_last_sibling (GNode *node)
929 g_return_val_if_fail (node != NULL, NULL);
931 while (node->next)
932 node = node->next;
934 return node;
937 void
938 g_node_children_foreach (GNode *node,
939 GTraverseFlags flags,
940 GNodeForeachFunc func,
941 gpointer data)
943 g_return_if_fail (node != NULL);
944 g_return_if_fail (flags <= G_TRAVERSE_MASK);
945 g_return_if_fail (func != NULL);
947 node = node->children;
948 while (node)
950 register GNode *current;
952 current = node;
953 node = current->next;
954 if (G_NODE_IS_LEAF (current))
956 if (flags & G_TRAVERSE_LEAFS)
957 func (current, data);
959 else
961 if (flags & G_TRAVERSE_NON_LEAFS)
962 func (current, data);