⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnode.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald * * GNode: N-way tree implementation. * Copyright (C) 1998 Tim Janik * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GLib Team and others 1997-2000.  See the AUTHORS * file for a list of people on the GLib Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GLib at ftp://ftp.gtk.org/pub/gtk/.  *//*  * MT safe */#ifdef HAVE_CONFIG_H#include "glibconfig.h"#endif#include "glib.h"#ifndef DISABLE_MEM_POOLS/* node allocation */struct _GAllocator /* from gmem.c */{  gchar         *name;  guint16        n_preallocs;  guint          is_unused : 1;  guint          type : 4;  GAllocator    *last;  GMemChunk     *mem_chunk;  GNode         *free_nodes; /* implementation specific */};G_LOCK_DEFINE_STATIC (current_allocator);static GAllocator *current_allocator = NULL;/* HOLDS: current_allocator_lock */static voidg_node_validate_allocator (GAllocator *allocator){  g_return_if_fail (allocator != NULL);  g_return_if_fail (allocator->is_unused == TRUE);  if (allocator->type != G_ALLOCATOR_NODE)    {      allocator->type = G_ALLOCATOR_NODE;      if (allocator->mem_chunk)	{	  g_mem_chunk_destroy (allocator->mem_chunk);	  allocator->mem_chunk = NULL;	}    }  if (!allocator->mem_chunk)    {      allocator->mem_chunk = g_mem_chunk_new (allocator->name,					      sizeof (GNode),					      sizeof (GNode) * allocator->n_preallocs,					      G_ALLOC_ONLY);      allocator->free_nodes = NULL;    }  allocator->is_unused = FALSE;}voidg_node_push_allocator (GAllocator *allocator){  G_LOCK (current_allocator);  g_node_validate_allocator (allocator);  allocator->last = current_allocator;  current_allocator = allocator;  G_UNLOCK (current_allocator);}voidg_node_pop_allocator (void){  G_LOCK (current_allocator);  if (current_allocator)    {      GAllocator *allocator;      allocator = current_allocator;      current_allocator = allocator->last;      allocator->last = NULL;      allocator->is_unused = TRUE;    }  G_UNLOCK (current_allocator);}/* --- functions --- */GNode*g_node_new (gpointer data){  GNode *node;  G_LOCK (current_allocator);  if (!current_allocator)    {       GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",						128);       g_node_validate_allocator (allocator);       allocator->last = NULL;       current_allocator = allocator;    }  if (!current_allocator->free_nodes)    node = g_chunk_new (GNode, current_allocator->mem_chunk);  else    {      node = current_allocator->free_nodes;      current_allocator->free_nodes = node->next;    }  G_UNLOCK (current_allocator);    node->data = data;  node->next = NULL;  node->prev = NULL;  node->parent = NULL;  node->children = NULL;    return node;}static voidg_nodes_free (GNode *node){  GNode *parent;  parent = node;  while (1)    {      if (parent->children)	g_nodes_free (parent->children);#ifdef ENABLE_GC_FRIENDLY      parent->data = NULL;      parent->prev = NULL;      parent->parent = NULL;      parent->children = NULL;#endif /* ENABLE_GC_FRIENDLY */      if (parent->next)	parent = parent->next;      else	break;    }    G_LOCK (current_allocator);  parent->next = current_allocator->free_nodes;  current_allocator->free_nodes = node;  G_UNLOCK (current_allocator);}#else /* DISABLE_MEM_POOLS */GNode*g_node_new (gpointer data){  GNode *node;  node = g_new0 (GNode, 1);    node->data = data;    return node;}static voidg_nodes_free (GNode *root){  GNode *node, *next;    node = root;  while (node != NULL)    {      next = node->next;      g_nodes_free (node->children);      g_free (node);      node = next;    }}#endifvoidg_node_destroy (GNode *root){  g_return_if_fail (root != NULL);    if (!G_NODE_IS_ROOT (root))    g_node_unlink (root);    g_nodes_free (root);}voidg_node_unlink (GNode *node){  g_return_if_fail (node != NULL);    if (node->prev)    node->prev->next = node->next;  else if (node->parent)    node->parent->children = node->next;  node->parent = NULL;  if (node->next)    {      node->next->prev = node->prev;      node->next = NULL;    }  node->prev = NULL;}GNode*g_node_copy (GNode *node){  GNode *new_node = NULL;    if (node)    {      GNode *child;            new_node = g_node_new (node->data);            for (child = g_node_last_child (node); child; child = child->prev)	g_node_prepend (new_node, g_node_copy (child));    }    return new_node;}GNode*g_node_insert (GNode *parent,	       gint   position,	       GNode *node){  g_return_val_if_fail (parent != NULL, node);  g_return_val_if_fail (node != NULL, node);  g_return_val_if_fail (G_NODE_IS_ROOT (node), node);    if (position > 0)    return g_node_insert_before (parent,				 g_node_nth_child (parent, position),				 node);  else if (position == 0)    return g_node_prepend (parent, node);  else /* if (position < 0) */    return g_node_append (parent, node);}GNode*g_node_insert_before (GNode *parent,		      GNode *sibling,		      GNode *node){  g_return_val_if_fail (parent != NULL, node);  g_return_val_if_fail (node != NULL, node);  g_return_val_if_fail (G_NODE_IS_ROOT (node), node);  if (sibling)    g_return_val_if_fail (sibling->parent == parent, node);    node->parent = parent;    if (sibling)    {      if (sibling->prev)	{	  node->prev = sibling->prev;	  node->prev->next = node;	  node->next = sibling;	  sibling->prev = node;	}      else	{	  node->parent->children = node;	  node->next = sibling;	  sibling->prev = node;	}    }  else    {      if (parent->children)	{	  sibling = parent->children;	  while (sibling->next)	    sibling = sibling->next;	  node->prev = sibling;	  sibling->next = node;	}      else	node->parent->children = node;    }  return node;}GNode*g_node_insert_after (GNode *parent,		     GNode *sibling,		     GNode *node){  g_return_val_if_fail (parent != NULL, node);  g_return_val_if_fail (node != NULL, node);  g_return_val_if_fail (G_NODE_IS_ROOT (node), node);  if (sibling)    g_return_val_if_fail (sibling->parent == parent, node);  node->parent = parent;  if (sibling)    {      if (sibling->next)	{	  sibling->next->prev = node;	}      node->next = sibling->next;      node->prev = sibling;      sibling->next = node;    }  else    {      if (parent->children)	{	  node->next = parent->children;	  parent->children->prev = node;	}      parent->children = node;    }  return node;}GNode*g_node_prepend (GNode *parent,		GNode *node){  g_return_val_if_fail (parent != NULL, node);    return g_node_insert_before (parent, parent->children, node);}GNode*g_node_get_root (GNode *node){  g_return_val_if_fail (node != NULL, NULL);    while (node->parent)    node = node->parent;    return node;}gbooleang_node_is_ancestor (GNode *node,		    GNode *descendant){  g_return_val_if_fail (node != NULL, FALSE);  g_return_val_if_fail (descendant != NULL, FALSE);    while (descendant)    {      if (descendant->parent == node)	return TRUE;            descendant = descendant->parent;    }    return FALSE;}/* returns 1 for root, 2 for first level children, * 3 for children's children... */guintg_node_depth (GNode *node){  register guint depth = 0;    while (node)    {      depth++;      node = node->parent;    }    return depth;}voidg_node_reverse_children (GNode *node){  GNode *child;  GNode *last;    g_return_if_fail (node != NULL);    child = node->children;  last = NULL;  while (child)    {      last = child;      child = last->next;      last->next = last->prev;      last->prev = child;    }  node->children = last;}guintg_node_max_height (GNode *root){  register GNode *child;  register guint max_height = 0;    if (!root)    return 0;    child = root->children;  while (child)    {      register guint tmp_height;            tmp_height = g_node_max_height (child);      if (tmp_height > max_height)	max_height = tmp_height;      child = child->next;    }    return max_height + 1;}static gbooleang_node_traverse_pre_order (GNode	    *node,			   GTraverseFlags    flags,			   GNodeTraverseFunc func,			   gpointer	     data){  if (node->children)    {      GNode *child;            if ((flags & G_TRAVERSE_NON_LEAFS) &&	  func (node, data))	return TRUE;            child = node->children;      while (child)	{	  register GNode *current;	  	  current = child;	  child = current->next;	  if (g_node_traverse_pre_order (current, flags, func, data))	    return TRUE;	}    }  else if ((flags & G_TRAVERSE_LEAFS) &&	   func (node, data))    return TRUE;    return FALSE;}static gbooleang_node_depth_traverse_pre_order (GNode		  *node,				 GTraverseFlags	   flags,				 guint		   depth,				 GNodeTraverseFunc func,				 gpointer	   data){  if (node->children)    {      GNode *child;            if ((flags & G_TRAVERSE_NON_LEAFS) &&	  func (node, data))	return TRUE;            depth--;      if (!depth)	return FALSE;            child = node->children;      while (child)	{	  register GNode *current;	  	  current = child;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -