예제 #1
0
파일: gnode.c 프로젝트: UIKit0/atv2
/**
 * g_node_prepend:
 * @parent: the #GNode to place the new #GNode under
 * @node: the #GNode to insert
 *
 * Inserts a #GNode as the first child of the given parent.
 *
 * Returns: the inserted #GNode
 */
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);
}
예제 #2
0
파일: gnode.c 프로젝트: UIKit0/atv2
/**
 * g_node_insert:
 * @parent: the #GNode to place @node under
 * @position: the position to place @node at, with respect to its siblings
 *     If position is -1, @node is inserted as the last child of @parent
 * @node: the #GNode to insert
 *
 * Inserts a #GNode beneath the parent at the given position.
 *
 * Returns: the inserted #GNode
 */
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);
}
예제 #3
0
gboolean
sort_func_priority_extended(GNode *node, gpointer data)
{
  struct VyattaNode *gp = (struct VyattaNode *) node->data;
  struct Config *gcfg = &(gp->_config);
  GNode *root_node = (GNode*)data;

  //WILL STOP AT DEPTH OF 10 REFERENCES
  //GET PARENT WORKING FIRST....

  //change action state of node according to enclosing behavior
  if (gcfg->_priority_extended) {
    //only if priority is specified.
    GNode *new_node = g_node_copy(node);

    //NOW, we need to figure out where this node belongs in the priority chain
    if (strncmp(gcfg->_priority_extended, "PARENT", 6) == 0) {
      //needs to walk up parents until priority is found and insert there....
      GNode *n = node;
      while (TRUE) {
        n = n->parent;
        if (n == NULL) {
          break;
        }
        gpointer nd = ((GNode*)n)->data;
        if (((struct VyattaNode*)nd)->_config._priority != LOWEST_PRIORITY) {
          //means we are done--found anchor in parent
          g_node_unlink(node);
          if (IS_DELETE(gp->_data._operation)) {
            g_node_insert_before(root_node,n,new_node);
          }
          else {
            g_node_insert_after(root_node,n,new_node);
          }
          break;
        }
      }
    }
  }
  return FALSE;
}
예제 #4
0
/* return the reversed thread tree */
GNode *procmsg_get_thread_tree(GSList *mlist)
{
	GNode *root, *parent, *node, *next;
	GHashTable *msgid_table;
	GRelation *subject_relation;
	MsgInfo *msginfo;
	const gchar *msgid;

	root = g_node_new(NULL);
	msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
	subject_relation = g_relation_new(2);
	g_relation_index(subject_relation, 0, g_str_hash, g_str_equal);

	for (; mlist != NULL; mlist = mlist->next) {
		msginfo = (MsgInfo *)mlist->data;
		parent = root;

		if (msginfo->inreplyto) {
			parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto);
			if (parent == NULL) {
				parent = root;
			}
		}
		node = g_node_insert_data_before
			(parent, parent == root ? parent->children : NULL,
			 msginfo);
		if ((msgid = msginfo->msgid) && g_hash_table_lookup(msgid_table, msgid) == NULL)
			g_hash_table_insert(msgid_table, (gchar *)msgid, node);

		/* CLAWS: add subject to relation (without prefix) */
		if (prefs_common.thread_by_subject) {
			subject_relation_insert(subject_relation, node);
		}
	}

	/* complete the unfinished threads */
	for (node = root->children; node != NULL; ) {
		parent = NULL;
		next = node->next;
		msginfo = (MsgInfo *)node->data;
		if (msginfo->inreplyto) { 
			parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto);
			/* node should not be the parent, and node should not 
			   be an ancestor of parent (circular reference) */
			if (parent && parent != node && 
			    !g_node_is_ancestor(node, parent)) {
				g_node_unlink(node);
				g_node_insert_before
					(parent, parent->children, node);
			}				
		}
		node = next;
	}

	if (prefs_common.thread_by_subject) {
		for (node = root->children; node && node != NULL;) {
			next = node->next;
			msginfo = (MsgInfo *) node->data;
			
			parent = subject_relation_lookup(subject_relation, msginfo);
			
			/* the node may already be threaded by IN-REPLY-TO, so go up 
			 * in the tree to 
			   find the parent node */
			if (parent != NULL) {
				if (g_node_is_ancestor(node, parent))
					parent = NULL;
				if (parent == node)
					parent = NULL;
			}
			
			if (parent) {
				g_node_unlink(node);
				g_node_append(parent, node);
			}

			node = next;
		}	
	}
	
	g_relation_destroy(subject_relation);
	g_hash_table_destroy(msgid_table);

	return root;
}
예제 #5
0
gboolean
sort_func(GNode *node, gpointer data, boolean priority_mode)
{
  struct VyattaNode *gp = (struct VyattaNode *) node->data;
  struct Data *d = &(gp->_data);
  GNode *root_node = (GNode*)data;
  d_dplog("commit2::sort_func(): %s, node count: %d",
          (d->_name ?  d->_name : "[n/a]"), g_node_n_children(root_node));

  //change action state of node according to enclosing behavior
  /* XXX this is ugly. originally the condition for the if is the following:
   *       (c1 && c2 || (c3 || c4) && c5)
   *
   *     this causes compiler warning for mixing && and || without (). the
   *     previous warning removal attempt changed the condition to the
   *     following:
   *       ((c1 && c2) || (c3 || (c4 && c5)))
   *
   *     which was incorrect (c3 and c4 should be at the same "level") and
   *     therefore was reverted.
   *
   *     now changing the condition to the following to avoid compiler
   *     warning:
   *       ((c1 && c2) || ((c3 || c4) && c5))
   *
   *     note that since the current goal is simply cleanup, no attempt is
   *     made to understand the logic here, and the change is purely based
   *     on operator precendence to maintain the original logic.
   *
   * XXX now removing deactivate-handling code, which involves c2.
   *
   *     note that c2 is (d->_disable_op != K_NO_DISABLE_OP), which means
   *     the node is "deactivated" (in working or active config or both).
   *     this in turn means that the (c1 && c2) part of the logic can only
   *     be true if the node is deactivated.
   *
   *     however, since activate/deactivate has not actually been exposed,
   *     this means that in actual usage the (c1 && c2) part is never true.
   *     therefore, we can simply remove the whole part, and the logic
   *     becomes:
   *       ((c3 || c4) && c5)
   */
  NODE_OPERATION op = d->_operation;
  if (((/* c3 */ IS_SET_OR_CREATE(op)) || (/* c4 */ IS_DELETE(op)))
      && (/* c5 */ IS_NOOP(((struct VyattaNode*)
                             (node->parent->data))->_data._operation))) {
    //first check if there is enclosing behavior
    boolean enclosing = FALSE;
    GNode *n = node;
    while (TRUE) {
      n = n->parent;
      vtw_def def = ((struct VyattaNode*)(n->data))->_config._def;
      if (def.actions[end_act].vtw_list_head
          || def.actions[begin_act].vtw_list_head) {
        enclosing = TRUE;
        break;
      }
      if (G_NODE_IS_ROOT(n) == TRUE) {
        break;
      }
    }

    //walk back up and flip operations until enclosing behavior
    if (enclosing == TRUE) {
      GNode *n = node;
      while (TRUE) {
        n = n->parent;
        vtw_def def = ((struct VyattaNode*)(n->data))->_config._def;
        if (((struct VyattaNode*)(n->data))->_data._operation == K_NO_OP) {
          /* XXX this is ugly. _operation is intended to be a bitmap, in which
           *     case it doesn't make sense to make it an enum type (should
           *     just be, e.g., int). this causes g++ to (rightly) complain.
           *     work around it for now to avoid impacting other code since
           *     the current goal is simply cleanup.
           */
          int op = ((struct VyattaNode*)(n->data))->_data._operation;
          op |= K_ACTIVE_OP;
          ((struct VyattaNode*)(n->data))->_data._operation
            = (NODE_OPERATION) op;
        }
        if (def.actions[end_act].vtw_list_head
            || def.actions[begin_act].vtw_list_head) {
          break;
        }
        if (G_NODE_IS_ROOT(n) == TRUE) {
          break;
        }
      }
    }
  }

  if (priority_mode) {
    int gprio = gp->_config._priority;
    if (gprio < LOWEST_PRIORITY) {
      // only if priority is specified.
      //unlink from original tree
      g_node_unlink(node);

      GNode *new_node = g_node_copy(node);
      GNode *sibling = root_node->children;
      //now iterate through siblings of root_node and compare priority
      
      while (sibling
             && gprio > ((struct VyattaNode*)(sibling->data))
                        ->_config._priority) {
        sibling = sibling->next;
        if (!sibling
            || gprio < ((struct VyattaNode*)(sibling->data))
                       ->_config._priority) {
          // XXX isn't this redundant??? just cleaning up so not changing it
          break;
        }
      }

      d_dplog("commit2::sort_func(): inserting %s into transaction, "
              "priority: %d BEFORE %d", d->_name, gprio,
              (sibling
               ? ((struct VyattaNode*)(sibling->data))->_config._priority
                 : LOWEST_PRIORITY));
      g_node_insert_before(root_node,sibling,new_node);
    }
  }
  else {
    if (g_node_depth(node) == 2) {
      d_dplog("commit2::sort_func(): insert %s into transaction", d->_name);
      GNode *new_node = g_node_copy(node);
      g_node_insert(root_node,-1,new_node); //make a flat structure for now
    }
  }
  return FALSE;
}