Bf_EdgeParams bf_get_node_edge_parameters(Node *node) {
  Bf_EdgeParams params = {0};

  for(uint32_t i=0; i<SLOT_COUNT; ++i) {
    if (is_backwards(node->slots[i])) {
      ASSERT(params.inv_idx == i || !is_backwards(node->slots[params.inv_idx]), "There can only be one backward edge");
      params.inv_idx = i;
    }
    else if (node->slots[i] && (!params.min_gen || params.min_gen > node->slots[i]->count)) {
      params.min_idx = i;
      params.min_gen = node->slots[i]->count;
    }
  }
  return params;
}
Ejemplo n.º 2
0
bool FindReplaceDialog::_search() {


	String text=get_search_text();
	uint32_t flags=0;

	if (is_whole_words())
		flags|=TextEdit::SEARCH_WHOLE_WORDS;
	if (is_case_sensitive())
		flags|=TextEdit::SEARCH_MATCH_CASE;
	if (is_backwards())
		flags|=TextEdit::SEARCH_BACKWARDS;

	int line,col;
	bool found = text_edit->search(text,flags,text_edit->cursor_get_line(),text_edit->cursor_get_column(),line,col);


	if (found) {
		print_line("found");
		text_edit->cursor_set_line(line);
		text_edit->cursor_set_column(col+text.length());
		text_edit->select(line,col,line,col+text.length());
		set_error("");
		return true;
	} else {

		set_error("Not Found!");
		return false;
	}

}
Bf_EdgeParams bf_backward_invert_edges__mut(Bf_TraverseState *state) {
  Bf_EdgeParams params = {0};
  Node *grand_pa = NULL;

  // Invariant : (grand_pa / NULL) <-- (parent)   (tail)
  while(1) {
    params = bf_get_node_edge_parameters(state->parent);
    ASSERT(state->parent->count <= state->tail->count, "While going backwards children always hold a higher gen than parents");
    ASSERT(is_backwards(state->parent->slots[params.inv_idx]), "There should always be a backward edge");
    grand_pa = follow_edge(state->parent->slots[params.inv_idx]);

    state->parent->count = params.min_gen ? params.min_gen : state->tail->count;
    ASSERT(state->parent->count >= state->next_tail_gen, "While going backwards we never go under the target generation");

    // we have found the closest ancestor of the node we are looking for
    if (state->parent->count == state->next_tail_gen) break;

    state->parent->slots[params.inv_idx] = state->tail;
    state->tail = state->parent;
    state->parent = grand_pa;
    ASSERT(state->parent, "We should not go past the root while going backwards");
  }
  // The edge params of the node where the traversal must change direction
  // Or the default value on a degenerate case : no need to backward to reach the next tail node
  return params;
}
Ejemplo n.º 4
0
bool FindReplaceDialog::_search() {

	String text = get_search_text();
	uint32_t flags = 0;

	if (is_whole_words())
		flags |= TextEdit::SEARCH_WHOLE_WORDS;
	if (is_case_sensitive())
		flags |= TextEdit::SEARCH_MATCH_CASE;
	if (is_backwards())
		flags |= TextEdit::SEARCH_BACKWARDS;

	int line = text_edit->cursor_get_line(), col = text_edit->cursor_get_column();

	if (is_backwards()) {
		col -= 1;
		if (col < 0) {
			line -= 1;
			if (line < 0) {
				line = text_edit->get_line_count() - 1;
			}
			col = text_edit->get_line(line).length();
		}
	}
	bool found = text_edit->search(text, flags, line, col, line, col);

	if (found) {
		// print_line("found");
		text_edit->unfold_line(line);
		text_edit->cursor_set_line(line);
		if (is_backwards())
			text_edit->cursor_set_column(col);
		else
			text_edit->cursor_set_column(col + text.length());
		text_edit->select(line, col, line, col + text.length());
		set_error("");
		return true;
	} else {

		set_error(TTR("Not found!"));
		return false;
	}
}
Ejemplo n.º 5
0
void dump_graph_dot_format(GraphHandle graph, const char* filepath) {
  FILE* dot_file = fopen(filepath, "w");
  LOG_INFO("Dumping graph to %s", filepath);
  ASSERT(dot_file, "Failed to open file");

  fprintf(dot_file, "digraph {\n");
  fprintf(dot_file, "  node  [ nodesep=1.5 ];\n");
  fprintf(dot_file, "  graph [ overlap=false; bgcolor=\"grey\" ];\n");
  fprintf(dot_file, "  edge  [ weight=0.5 ];\n");

  for(uint32_t i=0; i<graph.vertex_count; ++i) {
    Node* node = (Node*)(graph.root + i);
    LOG_TRACE("Printing %u : %s", i, node->name);

    if (i == 0 || i == graph.vertex_count-1)
      fprintf_node_dot_format(dot_file, node, "cyan");
    else if (is_leaf_node(node))
      fprintf_node_dot_format(dot_file, node, "gold");
    else if (is_leaf_node_ignore_back(node))
      fprintf_node_dot_format(dot_file, node, "orange");
    else
      fprintf_node_dot_format(dot_file, node, NULL);

    for(uint32_t slot=0; slot < SLOT_COUNT; ++slot) {
      Node* child = follow_edge(node->slots[slot]);
      if (child)
        if (is_backwards(node->slots[slot]))
          fprintf_edge_dot_format(dot_file, node, child, "red");
        else if (get_flags_on_edge(node->slots[slot], SET_TRAVERSE_FLAG))
          fprintf_edge_dot_format(dot_file, node, child, "blue");
        else if (get_flags_on_edge(node->slots[slot], SET_VISIT_FLAG))
          fprintf_edge_dot_format(dot_file, node, child, "green4");
        else
          fprintf_edge_dot_format(dot_file, node, child, NULL);
      else if (is_backwards(node->slots[slot]))
        fprintf_edge_dot_format(dot_file, node, NULL, "red");
    }
  }

  fprintf(dot_file, "}\n");
  fclose(dot_file);
}
uint32_t bf_pathological_branch_loop_back(Node *node, uint32_t child_edge) {
  Node *child = node->slots[child_edge];
  uint32_t is_a_loop = child == node;
  // The inverted edge we write while traversing forward serves as a "breadcrumb" 
  // to identify the previous nodes of this branch
  for(uint32_t i=0; i<SLOT_COUNT && !is_a_loop; ++i) 
    if (is_backwards(child->slots[i])) {
      MY_DTRACE_PROBE2(patho_branch_loop, node, child_edge);
      is_a_loop = 1;
    }
  return is_a_loop;
}
void pr_advance_to_next_child__mut(Pr_TraverseState* state) {
  uint32_t next_slot = state->next_slot;
  Node** cur_slots = state->current->slots;
  ASSERT(!is_backwards(cur_slots[next_slot]), "At %s we are going backward instead of forward", 
         ((Node*)follow_edge(cur_slots[next_slot]))->name);
  Node* tmp_grand_pa = state->previous;

  state->previous = state->current;
  state->current = follow_edge(cur_slots[next_slot]);
  state->previous->slots[next_slot] = set_flags_on_edge(tmp_grand_pa, SET_TRAVERSE_FLAG|SET_BACK_FLAG|state->tag_token);
  state->next_slot = pr_next_untraversed_slot(state->current, state->tag_token, 0);
}
uint32_t bf_backward_prune_exhausted_branch__mut(Bf_TraverseState *state) {
  Bf_EdgeParams params = {0};
  // Invariant : the tail node has no forward edges
  while (!params.min_gen) {
    ASSERT(state->parent, "We should not go past the root while pruning backwards");
    params = bf_get_node_edge_parameters(state->parent);
    ASSERT(is_backwards(state->parent->slots[params.inv_idx]), "There should always be a backward edge");

    state->tail = state->parent;
    state->parent = follow_edge(state->parent->slots[params.inv_idx]);
  }
  // we reached a node with ancestors in the visit queue, recalculate generation after prune
  state->tail->count = params.min_gen;
  // we keep the invariant that between parent and tail there is no edge
  state->tail->slots[params.inv_idx] = NULL;
  ASSERT(state->tail->count >= state->next_tail_gen, "When we cannot prune further we should be at a higher generation");
  return state->tail->count;
}
uint32_t bf_visit_childs_tag_generation__mut(Node* node, VisitorState* visit_state, Visitor_t visitor, uint32_t start_gen) {
  uint32_t visit_count = 0;

  for(uint32_t i=0; i<SLOT_COUNT; ++i) {
    ASSERT(!is_backwards(node->slots[i]), "The tail node can only have edges going forward");
    if (node->slots[i]) {
      Node *child = node->slots[i];
      // cycle detected, remove edge to avoid recursion
      if (child->count) {
        ASSERT(child->count <= start_gen, "Weird cycle to the future");
        node->slots[i] = NULL;
      }
      else {
        visit_count += 1;
        child->count = start_gen + visit_count;
        visitor(visit_state, child);
      }
    }
  }
  // A node has the same generation as the smallest of its visited ancestors
  if(visit_count)
    node->count = start_gen + 1;
  return visit_count;
}