Beispiel #1
0
/**
 * g_node_insert_after:
 * @parent: the #GNode to place @node under
 * @sibling: the sibling #GNode to place @node after. 
 *     If sibling is %NULL, the node is inserted as the first child of @parent.
 * @node: the #GNode to insert
 *
 * Inserts a #GNode beneath the parent after the given sibling.
 *
 * Returns: the inserted #GNode
 */
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;
}
Beispiel #2
0
/**
 * g_node_destroy:
 * @root: the root of the tree/subtree to destroy
 *
 * Removes @root and its children from the tree, freeing any memory
 * allocated.
 */
void
g_node_destroy (GNode *root)
{
  g_return_if_fail (root != NULL);
  
  if (!G_NODE_IS_ROOT (root))
    g_node_unlink (root);
  
  g_nodes_free (root);
}
Beispiel #3
0
gboolean insert_in_tree(GNode *directory, File *file)
{
	GNode *new_file, *file_ptr, *dir_ptr;
	int position;

	if (file->name[0] == '.' && FILE(directory)->show_dotfiles == FALSE) {
		insert_sorted_in_dotfiles(directory, file);

		return FALSE;
	}

	new_file = insert_sorted_in_tree(directory, file);
	for (dir_ptr = directory; !G_NODE_IS_ROOT(dir_ptr); dir_ptr = dir_ptr->parent) {
		if (FILE(dir_ptr)->open == FALSE)
			return FALSE;
	}
	if (FILE(dir_ptr)->open == FALSE)
		return FALSE;

	file_ptr = get_previous_file(new_file);
	position = g_list_position(lines, FILE(file_ptr)->line);
	lines = g_list_insert(lines, new_file, position + 1);
	file->line = g_list_nth(lines, position + 1);

	if (g_list_length(first_line) - g_list_length(last_line) + 1) {
		if (g_list_previous(first_line) == file->line)
			first_line = file->line;
		else if (g_list_next(last_line) == file->line)
			last_line = file->line;
	}
	if (g_list_position(lines, first_line) <= position + 1 &&
			position + 1 <= g_list_position(lines, last_line)) {
		if (position + 1 < g_list_position(lines, selected_line)) {
			if (g_list_length(first_line) <= getmaxy(tree_window))
				print_lines(first_line, last_line, FALSE);
			else {
				first_line = g_list_next(first_line);
				print_lines(first_line, file->line, FALSE);
			}
		} else {
			if (g_list_length(first_line) > getmaxy(tree_window))
				last_line = g_list_previous(last_line);

			if (g_node_last_sibling(new_file) == new_file)
				print_lines(g_list_previous(file->line), last_line, FALSE);
			else
				print_lines(file->line, last_line, FALSE);
		}

		return TRUE;
	}

	return FALSE;
}
static gboolean
source_viewer_traverse (GNode *node,
                        gpointer user_data)
{
	ESourceViewer *viewer;
	ESource *source;
	GHashTable *source_index;
	GtkTreeRowReference *reference = NULL;
	GtkTreeView *tree_view;
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;

	/* Skip the root node. */
	if (G_NODE_IS_ROOT (node))
		return FALSE;

	viewer = E_SOURCE_VIEWER (user_data);

	source_index = viewer->source_index;

	tree_view = GTK_TREE_VIEW (viewer->tree_view);
	model = gtk_tree_view_get_model (tree_view);

	if (node->parent != NULL && node->parent->data != NULL)
		reference = g_hash_table_lookup (
			source_index, node->parent->data);

	if (gtk_tree_row_reference_valid (reference)) {
		GtkTreeIter parent;

		path = gtk_tree_row_reference_get_path (reference);
		gtk_tree_model_get_iter (model, &parent, path);
		gtk_tree_path_free (path);

		gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent);
	} else
		gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);

	/* Source index takes ownership. */
	source = g_object_ref (node->data);

	path = gtk_tree_model_get_path (model, &iter);
	reference = gtk_tree_row_reference_new (model, path);
	g_hash_table_insert (source_index, source, reference);
	gtk_tree_path_free (path);

	source_viewer_update_row (viewer, source);

	return FALSE;
}
Beispiel #5
0
static gboolean
free_node (GNode *node, xmms_magic_entry_t *entry)
{
	if (G_NODE_IS_ROOT (node)) {
		gpointer *data = node->data;

		/* this isn't a magic entry, but the description of the tree */
		g_free (data[0]); /* desc */
		g_free (data[1]); /* mime */
		g_free (data);
	} else {
		xmms_magic_entry_free (entry);
	}

	return FALSE; /* continue traversal */
}
Beispiel #6
0
void print_parents_lines(GList *line)
{
	GNode *file_ptr;
	int depth;

	for (file_ptr = NODE(line)->parent, depth = g_node_depth(file_ptr) - 1;
			!G_NODE_IS_ROOT(file_ptr); file_ptr = file_ptr->parent, depth--) {
		if (file_ptr != g_node_last_sibling(file_ptr))
			mvwaddch(tree_window, g_list_position(first_line, line),
					2 * depth - 2, ACS_VLINE);
		else
			mvwaddch(tree_window, g_list_position(first_line, line),
					2 * depth - 2, ' ');
		mvwaddch(tree_window, g_list_position(first_line, line), 2 * depth - 1, ' ');
	}
}
Beispiel #7
0
/**
 * g_node_insert_before:
 * @parent: the #GNode to place @node under
 * @sibling: the sibling #GNode to place @node before. 
 *     If sibling is %NULL, the node is inserted as the last child of @parent.
 * @node: the #GNode to insert
 *
 * Inserts a #GNode beneath the parent before the given sibling.
 *
 * Returns: the inserted #GNode
 */
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;
}
Beispiel #8
0
/**
 * 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);
}
Beispiel #9
0
void print_line(GList *line)
{
	int line_number = g_list_position(first_line, line);
	GNode *file = NODE(line);
	int depth = g_node_depth(file) - 1;
	char *link_str;

	wmove(tree_window, line_number, 0);
	wclrtoeol(tree_window);

	if (line == selected_line)
		wattron(tree_window, A_REVERSE);

	if (G_NODE_IS_ROOT(file)) {
		wattron(tree_window, A_BOLD);
		waddnstr(tree_window, FILE(file)->name, getmaxx(tree_window) - 1);
		if (!g_str_has_suffix(FILE(file)->name, "/"))
			waddch(tree_window, '/');
		wattroff(tree_window, A_BOLD);
	} else {
		if (file != g_node_last_sibling(file))
			mvwaddch(tree_window, line_number, 2 * depth - 2, ACS_LTEE);
		else
			mvwaddch(tree_window, line_number, 2 * depth - 2, ACS_LLCORNER);

		waddch(tree_window, ACS_HLINE);
		if (FILE(file)->link == TRUE) {
			link_str = g_strdup_printf("%s -> %s", FILE(file)->name,
					FILE(file)->link_path);
			waddnstr(tree_window, link_str, getmaxx(tree_window) - 2 * depth - 1);
			free(link_str);
		} else
			waddnstr(tree_window, FILE(file)->name,
					getmaxx(tree_window) - 2 * depth - 1);

		if (FILE(file)->type == directory_type && ((FILE(file)->link == TRUE &&
						!g_str_has_suffix(FILE(file)->link_path, "/")) ||
					(FILE(file)->link == FALSE &&
					 !g_str_has_suffix(FILE(file)->name, "/"))))
			waddch(tree_window, '/');
		print_parents_lines(line);
	}
	wattroff(tree_window, A_REVERSE);
}
Beispiel #10
0
static gboolean mh_remove_missing_folder_items_func(GNode *node, gpointer data)
{
	FolderItem *item;
	gchar *path;

	cm_return_val_if_fail(node->data != NULL, FALSE);

	if (G_NODE_IS_ROOT(node))
		return FALSE;

	item = FOLDER_ITEM(node->data);

	path = folder_item_get_path(item);
	if (!is_dir_exist(path)) {
		debug_print("folder '%s' not found. removing...\n", path?path:"(null)");
		folder_item_remove(item);
	}
	g_free(path);

	return FALSE;
}
Beispiel #11
0
gboolean remove_from_tree(GNode *file, gboolean unmount)
{
	int position = g_list_position(lines, FILE(file)->line);
	gboolean refresh_needed = FALSE;
	GList *line_ptr, *line_ptr2;
	GNode *dir_ptr;

	if (G_NODE_IS_ROOT(file)) {
		endwin();
		clean_up();
		printf("The tree root was removed\n");
		exit(EXIT_SUCCESS);
	}
	if (g_node_is_ancestor(file, NODE(selected_line)))
		select_file(file);
	if (FILE(file)->type == directory_type) {
		close_directory(file);
		destroy_directory_content_real(file, FALSE);
		if (unmount)
			return TRUE;
	} else if (FILE(file)->type == file_type) {
		for (dir_ptr = file->parent; !G_NODE_IS_ROOT(dir_ptr);
				dir_ptr = dir_ptr->parent) {
			if (FILE(dir_ptr)->open == FALSE) {
				g_node_unlink(file);
				return FALSE;
			}
		}
		if (FILE(dir_ptr)->open == FALSE) {
			g_node_unlink(file);
			return FALSE;
		}
	}
	g_node_unlink(file);

	if (g_list_position(lines, first_line) <= position &&
			position <= g_list_position(lines, last_line)) {
		if (first_line == FILE(file)->line && selected_line == FILE(file)->line) {
			selected_line = first_line = g_list_previous(first_line);
			lines = g_list_delete_link(lines, FILE(file)->line);
			print_lines(first_line, first_line, FALSE);
		} else if (position < g_list_position(lines, selected_line)) {
			if (first_line == FILE(file)->line)
				first_line = g_list_next(first_line);
			line_ptr = g_list_previous(FILE(file)->line);
			lines = g_list_delete_link(lines, FILE(file)->line);
			if ((line_ptr2 = g_list_previous(first_line)) != NULL) {
				first_line = line_ptr2;
				print_lines(first_line, line_ptr, FALSE);
			} else if ((line_ptr2 = g_list_next(last_line)) != NULL) {
				last_line = line_ptr2;
				print_lines(line_ptr, last_line, FALSE);
			} else
				print_lines(line_ptr, last_line, TRUE);
		} else {
			if (FILE(file)->line == selected_line)
				selected_line = g_list_previous(selected_line);
			if (last_line == FILE(file)->line)
				last_line = g_list_previous(last_line);
			line_ptr = g_list_previous(FILE(file)->line);
			lines = g_list_delete_link(lines, FILE(file)->line);
			if ((line_ptr2 = g_list_next(last_line)) != NULL) {
				last_line = line_ptr2;
				print_lines(line_ptr, last_line, FALSE);
			} else
				print_lines(line_ptr, last_line, TRUE);
		}
		refresh_needed = TRUE;
	} else {
		if (last_line == g_list_previous(FILE(file)->line)) {
			lines = g_list_delete_link(lines, FILE(file)->line);
			print_lines(last_line, last_line, FALSE);
			refresh_needed = TRUE;
		} else
			lines = g_list_delete_link(lines, FILE(file)->line);
	}
	free_node_data(file, NULL);
	g_node_destroy(file);

	return refresh_needed;
}
Beispiel #12
0
void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
{
    char *trailer = NULL;

    uint8_t offset_size = 0;
    uint8_t dict_param_size = 0;
    uint64_t num_objects = 0;
    uint64_t root_object = 0;
    uint64_t offset_table_index = 0;

    plist_t *nodeslist = NULL;
    uint64_t i = 0;
    uint64_t current_offset = 0;
    char *offset_table = NULL;
    uint32_t j = 0, str_i = 0, str_j = 0;
    uint32_t index1 = 0, index2 = 0;


    //first check we have enough data
    if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE))
        return;
    //check that plist_bin in actually a plist
    if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0)
        return;
    //check for known version
    if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0)
        return;

    //now parse trailer
    trailer = (char *) (plist_bin + (length - BPLIST_TRL_SIZE));

    offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX];
    dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX];
    num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX);
    root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX);
    offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX);

    if (num_objects == 0)
        return;

    //allocate serialized array of nodes
    nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects);

    if (!nodeslist)
        return;

    //parse serialized nodes
    offset_table = (char *) (plist_bin + offset_table_index);
    for (i = 0; i < num_objects; i++)
    {
        char *obj = NULL;
        current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size);

        obj = (char *) (plist_bin + current_offset);
        nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj);
    }

    //setup children for structured types
    for (i = 0; i < num_objects; i++)
    {

        plist_data_t data = plist_get_data(nodeslist[i]);

        switch (data->type)
        {
        case PLIST_DICT:
            for (j = 0; j < data->length; j++)
            {
                str_i = j * dict_param_size;
                str_j = (j + data->length) * dict_param_size;

                index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size);
                index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size);

                //first one is actually a key
                plist_get_data(nodeslist[index1])->type = PLIST_KEY;

                if (index1 < num_objects)
                {
                    if (G_NODE_IS_ROOT(nodeslist[index1]))
                        g_node_append(nodeslist[i], nodeslist[index1]);
                    else
                        g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL));
                }

                if (index2 < num_objects)
                {
                    if (G_NODE_IS_ROOT(nodeslist[index2]))
                        g_node_append(nodeslist[i], nodeslist[index2]);
                    else
                        g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index2], copy_plist_data, NULL));
                }
            }

            free(data->buff);
            break;

        case PLIST_ARRAY:
            for (j = 0; j < data->length; j++)
            {
                str_j = j * dict_param_size;
                index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size);

                if (index1 < num_objects)
                {
                    if (G_NODE_IS_ROOT(nodeslist[index1]))
                        g_node_append(nodeslist[i], nodeslist[index1]);
                    else
                        g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL));
                }
            }
            free(data->buff);
            break;
        default:
            break;
        }
    }

    *plist = nodeslist[root_object];
    free(nodeslist);
}
Beispiel #13
0
gboolean
ada_gnode_is_root (GNode * node)
{
  return G_NODE_IS_ROOT (node);
}
Beispiel #14
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;
}