static void binary_export_nodes (FILE * file, Node *node, int level) { while (node) { int attributes=0; {Node_AttItem *att=node->attrib; while(att){ attributes++; att=att->next; } } fwrite(&level, sizeof(int), 1, file); fwrite(&attributes, sizeof(int), 1, file); {Node_AttItem *att=node->attrib; while(att){ int len=strlen(att->name); fwrite(&len,sizeof(int),1,file); fwrite(att->name,1,len, file); len=strlen(att->data); fwrite(&len,sizeof(int),1,file); fwrite(att->data,1,len, file); att=att->next; } } if (node_right (node)) { binary_export_nodes (file, node_right (node), level + 1); } node = node_down (node); } }
Node *node_backrecurse (Node *node) { if (node_up (node)) { node = node_up (node); while (node_right (node)) { node = node_right (node); node = node_bottom (node); } return (node); } return (node_left (node)); }
Node *node_recurse (Node *node) { if (node_right (node)) return node_right (node); if (node_down (node)) return node_down (node); while (node_left (node)) { if (node_down (node_left (node))) return node_down (node_left (node)); node = node_left (node); } return 0; }
static int addc (int argc,char **argv, void *data) { Node *pos = (Node *) data; Node *tnode; if(argc==1){ cli_outfunf("usage: %s <entry> [new subentry]",argv[0]); return 0; } tnode = node_exact_match (argv[1], pos); if (!tnode) { cli_outfun ("specified parent not found"); return (int) pos; } if (node_right (tnode)) { tnode=node_bottom(tnode); } else { tnode=node_insert_right(tnode); } if(argc==2) node_set (tnode, TEXT, ""); else node_set (tnode, TEXT, argv[2]); return (int) pos; }
static int cd (int argc, char **argv, void *data) { Node *pos = (Node *) data; Node *tnode = pos; if(argc==1){ return (int)node_root(pos); } if (!strcmp (argv[1], "..")){ if (node_left (tnode) != 0) return (int) (node_left (tnode)); } tnode = path2node (argv[1], pos); if (tnode) { tnode = node_right (tnode); } if (!tnode) { cli_outfun ("no such node\n"); return (int) pos; } return (int) tnode; return (int) pos; }
static Node *node_forced_up ( Node *node) { if (node_up (node) && node_getflag( node_up (node), F_expanded)) { node = node_up (node); while (node_right (node) && node_getflag(node,F_expanded)) { node = node_right (node); node = node_bottom (node); } return (node); } else { if (node_up (node)) return (node_up (node)); else return (node_left (node)); } return node_left (node); }
/* a traversal calculation of completion level */ int node_calc_complete (Node *node) { int percent_sum = 0; int nodes = 0; if (strcmp(fixnullstring(node_get(node,"type")),"todo")) return -1; /* node has no completion status */ if (node_get(node,"done") && !strcmp(node_get(node,"done"),"yes")) return 2000; /* this node is done */ if (node_getval (node,"percent_done") != -1) return node_getval (node,"percent_done") * 10; if (!node_right (node)) return 0; /* no undone children,.. completly undone */ node = node_right (node); while (node) { switch (node_calc_complete (node)) { case -1: break; case 2000: percent_sum += 1000; nodes++; break; default: percent_sum += node_calc_complete (node); nodes++; break; } node = node_down (node); } if (nodes) return (percent_sum) / (nodes); return 0; }
static void heap_fix_down(struct heap *heap) { uint8_t *tree = heap->head; const size_t size = heap->size; for (size_t i = 0; i < size; ++i) { const size_t left = node_left(i); const size_t right = node_right(i); if (right < size && tree[left] > tree[right]) exchange(&tree[left], &tree[right]); if (left < size && tree[i] > tree[left]) exchange(&tree[i], &tree[left]); } }
int node_calc_size (Node *node) { int size_sum = 0; int nodes = 0; if (strcmp(fixnullstring(node_get(node,"type")),"todo")) return -1; /* node has no completion status */ if (node_getval (node,"size") != -1) return node_getval (node,"size"); if (!node_right (node)) { /* leaf node */ if (node_getval (node,"size") != -1) return node_getval (node,"size"); else return 10; /* default size value */ } node = node_right (node); while (node) { switch (node_calc_complete (node)) { case -1: break; default: size_sum += node_calc_size (node); nodes++; break; } node = node_down (node); } if (nodes) return (size_sum); return 10; /* no of the children had any time,.. so we default to 1 */ }
static void* stats_cmd (int argc, char **argv, void *data) { int words = 0, leaves = 0, nodes = 0; Node *pos = (Node *) data; Node *node = node_root (pos); while (node) { nodes++; words += count_words ((unsigned char *)fixnullstring (node_get (node, TEXT))); if (!node_right (node)) leaves++; node = node_recurse (node); } cli_outfunf ("nodes:%i, leaves:%i words:%i", nodes, leaves, words); return pos; }
static int ls (int argc, char **argv, void *data) { Node *pos = (Node *) data; Node *tnode; int recurse = 0; int indicate_sub = 1; int startlevel; tnode = node_top (pos); startlevel = nodes_left (tnode); while (tnode) { if (recurse) { int j; for (j = nodes_left (tnode); j > startlevel; j--) { printf ("\t"); } } cli_outfunf( "%s %s %s",fixnullstring(node_get (tnode, TEXT)), indicate_sub? node_right(tnode)?"(..)":"" :"", tnode==pos?"<":"" ); if (recurse) { tnode = node_recurse (tnode); if (nodes_left (tnode) < startlevel) tnode = 0; } else { tnode = node_down (tnode); } } return (int) pos; }
Node *evilloop (Node *pos) { cli_outfun = set_status; while (!quit_tines) { Tbinding *binding; ui_draw (pos, inputbuf, 0); binding = parsekey (ui_input (), ui_current_scope); do { switch (binding->action) { case ui_action_quit: remove_temp (&pos); quit_tines = 1; break; case ui_action_command: if(!string_isoneof(binding->action_param, no_remove_temp_commands)) remove_temp (&pos); pos = docmd (pos, binding->action_param); if(!string_isoneof(binding->action_param,keep_inputbuf)) inputbuf[0] = 0; break; case ui_action_top: remove_temp (&pos); inputbuf[0] = 0; pos = node_top (pos); break; case ui_action_bottom: remove_temp (&pos); inputbuf[0] = 0; pos = node_bottom (pos); break; case ui_action_up: if (!remove_temp (&pos)) { if(forced_up){ if (node_forced_up (pos)){ pos = node_forced_up (pos); } } else { if (node_up (pos)){ pos = node_up (pos); } } } inputbuf[0] = 0; break; case ui_action_down: if (!remove_temp (&pos)) { if(forced_down){ if(node_forced_down(pos)) pos = node_forced_down (pos); } else { if(node_down(pos)) pos = node_down (pos); } inputbuf[0] = 0; break; } case ui_action_pagedown: remove_temp (&pos); inputbuf[0] = 0; { int n; for (n = 0; n < tines_nodes_down; n++) if (node_down (pos)) { pos = node_down (pos); } } break; case ui_action_pageup: remove_temp (&pos); inputbuf[0] = 0; { int n; for (n = 0; n < tines_nodes_up; n++) if (node_up (pos)) pos = node_up (pos); } break; case ui_action_left: if (!remove_temp (&pos)) { if (node_left (pos)) pos = node_left (pos); } inputbuf[0] = 0; break; case ui_action_right: if (node_right (pos)) { pos = node_right (pos); } else { if (fixnullstring (node_get (pos, TEXT))[0]) { node_insert_right (pos); if (node_getflag (pos, F_temp)) node_setflag (pos, F_temp, 0); if (!strcmp(fixnullstring(node_get(pos,"type")),"todo")){ node_set (node_right (pos), "type","todo"); node_set (node_right (pos), "done","no"); } node_setflag (node_right (pos), F_temp, 1); pos = node_right (pos); } } inputbuf[0] = 0; break; case ui_action_complete: if (strcmp (inputbuf, fixnullstring (node_get (pos, TEXT))) == 0) { if (node_right (pos)) { pos = node_right (pos); } else { if (fixnullstring (node_get (pos, TEXT))[0]) { node_insert_right (pos); if (node_getflag (pos, F_temp)) node_setflag (pos, F_temp, 0); if (!strcmp(fixnullstring(node_get(pos,"type")),"todo")){ node_set (node_right (pos), "type","todo"); node_set (node_right (pos), "done","no"); } node_setflag (node_right (pos), F_temp, 1); pos = node_right (pos); } } inputbuf[0] = 0; } else { strcpy (inputbuf, fixnullstring (node_get (pos, TEXT))); } break; case ui_action_cancel: if (node_getflag (pos, F_temp)) { pos = node_remove (pos); } else { /*stop = ui_quit (pos); */ } inputbuf[0] = 0; break; case ui_action_backspace: if (!strlen (inputbuf)) { /*pos = ui_remove (pos); */ } else { inputbuf[strlen (inputbuf) - 1] = 0; if (node_getflag (pos, F_temp)) if (node_up (pos)) pos = node_remove (pos); } break; case ui_action_unbound: undefined_key (ui_scope_names[ui_current_scope], binding->key != 1000 ? binding->key : *((int *) &binding-> action_param[0])); case ui_action_ignore: break; default: if (binding->action > 31 && binding->action < 255) { /* input for buffer */ inputbuf[strlen (inputbuf) + 1] = 0; inputbuf[strlen (inputbuf)] = binding->action; } else undefined_key (ui_scope_names[ui_current_scope], binding->key != 1000 ? binding-> key : *((int *) &binding-> action_param[0])); break; } } while ((++binding)->key == 999); if (strlen (inputbuf)) { if (node_getflag (pos, F_temp)) { node_set (pos, TEXT, inputbuf); } else { if (node_match (inputbuf, pos)) { pos = node_match (inputbuf, pos); } else { if (add_at_top) { pos = node_insert_up (node_top (pos)); } else { pos = node_insert_down (node_bottom (pos)); } node_setflag (pos, F_temp, 1); node_set (pos, TEXT, inputbuf); if (node_left (pos)) if (!strcmp(fixnullstring(node_get(node_left(pos),"type")),"todo")){ node_set (pos, "type","todo"); node_set (pos, "done","no"); } } } } else { docmd(pos, "autosave_check_timeout"); } } return pos; }
int calc_percentage_size (Node *node, int *retsize) { int percentage = node_getval (node,"percent_done"); int size = node_getval (node,"size"); int size_todo = 0; int size_done = 0; int childnodes = 0; Node *tnode; if (strcmp(fixnullstring(node_get(node,"type")),"todo")) { /* bail out if not todo info set */ *retsize = -1; return -1; } tnode = node_right (node); while (tnode) { int rsize, rperc; rperc = calc_percentage_size (tnode, &rsize); switch (rperc) { case -1: break; case 2000: if (rsize != -1) size_todo += rsize; size_done += rsize * 100; childnodes++; break; default: if (rsize != -1) size_todo += rsize; size_done += rsize * rperc; childnodes++; break; } tnode = node_down (tnode); } if (!childnodes) { size_todo = def_size; size_done = 0; } if (size != -1) { if (childnodes) size += size_todo; } else { size = size_todo; } *retsize = size; if (node_get(node,"done") && !strcmp(node_get(node,"done"),"yes")) return 2000; if (percentage != -1) { return percentage; } else { percentage = size_done / size_todo; } return percentage; }
void node_delete(Node *node) { if (*node) { if (!node_left(*node) && !node_right(*node)) { Node tmp = *node; *node = NULL; free(node_value(tmp)); free(tmp); return; } else if (!node_left(*node)) { Node tmp = *node; *node = node_right(*node); free(tmp->value); free(tmp); return; } else if (!node_right(*node)) { Node tmp = *node; *node = node_left(*node); free(tmp->value); free(tmp); return; } else { Node successor = node_right((*node)); Node successorParent = (*node); while(successor->left) { successorParent = successor; successor = node_left(successor); } if (node_right(*node) == successor) { Node temp = *node; set_left(successor, node_left(*node)); *node = successor; free(temp->value); free(temp); return; } else { set_left(successorParent, node_right(successor)); set_left(successor, node_left(*node)); set_right(successor, node_right(*node)); Node temp = *node; *node = successor; free(temp->value); free(temp); return; } } } }