/** * 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; }
/** * 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); }
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; }
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 */ }
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, ' '); } }
/** * 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; }
/** * 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); }
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); }
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; }
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; }
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); }
gboolean ada_gnode_is_root (GNode * node) { return G_NODE_IS_ROOT (node); }
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; }