Example #1
0
void Command::parse_parts ()
{
    string& current_part = *(parts_.begin ());

    trim (current_part);
    if (ends_with (current_part, "&"))
    {
        parallel_ = true;
        current_part.erase (current_part.length () - 1);
    }

    vector<string> separators = {"&&", "||", "|"};

    for (auto const & separator : separators)
    {
        for (auto i = parts_.begin (); i != parts_.end (); ++ i)
        {
            if (std::find (separators.begin (), separators.end (), *i) != separators.end ())
            {
                continue;
            }

            unsigned long pos;
            while ((pos = (*i).find (separator)) != string::npos)
            {
                string& part = *i;

                auto right = part.substr (pos + separator.length (), string::npos);
                part.erase (pos, string::npos);

                ++ i;

                parts_.insert (i, separator);
                parts_.insert (i, right);

                -- i;
            }
        }
    }
}
Example #2
0
void mdb_shell::filter_metaprogram() {
  assert(mp);

  using boost::starts_with;
  using boost::ends_with;
  using boost::trim_copy;

  using vertex_descriptor = metaprogram::vertex_descriptor;
  using edge_descriptor = metaprogram::edge_descriptor;
  using edge_property = metaprogram::edge_property;
  using discovered_t = metaprogram::discovered_t;

  static const std::string wrap_prefix = "metashell::impl::wrap<";
  static const std::string wrap_suffix = ">";

  // TODO this check could be made more strict,
  // since we now whats inside wrap<...> (mp->get_evaluation_result)
  auto is_wrap_type = [](const std::string& type) {
    return starts_with(type, wrap_prefix) && ends_with(type, wrap_suffix);
  };

  std::string env_buffer = env.get();
  int line_number = std::count(env_buffer.begin(), env_buffer.end(), '\n');

  // First disable everything
  for (edge_descriptor edge : mp->get_edges()) {
    mp->get_edge_property(edge).enabled = false;
  }

  // We will traverse the interesting edges later
  std::stack<edge_descriptor> edge_stack;

  // Enable the interesting root edges
  for (edge_descriptor edge : mp->get_out_edges(mp->get_root_vertex())) {
    edge_property& property = mp->get_edge_property(edge);
    const std::string& target_name =
      mp->get_vertex_property(mp->get_target(edge)).name;
    // Filter out edges, that is not instantiated by the entered type
    if (property.point_of_instantiation.name == internal_file_name &&
        property.point_of_instantiation.row == line_number + 2 &&
        (property.kind == instantiation_kind::template_instantiation ||
        property.kind == instantiation_kind::memoization) &&
        (!is_wrap_type(target_name) ||
         property.kind != instantiation_kind::memoization))
    {
      property.enabled = true;
      edge_stack.push(edge);
    }
  }

  discovered_t discovered(mp->get_num_vertices());
  // Traverse the graph to enable all edges which are reachable from the
  // edges enabled above
  while (!edge_stack.empty()) {
    edge_descriptor edge = edge_stack.top();
    edge_stack.pop();

    assert(mp->get_edge_property(edge).enabled);

    vertex_descriptor vertex = mp->get_target(edge);

    if (discovered[vertex]) {
      continue;
    }

    for (edge_descriptor out_edge : mp->get_out_edges(vertex)) {
      edge_property& property = mp->get_edge_property(out_edge);
      if (property.kind == instantiation_kind::template_instantiation ||
         property.kind == instantiation_kind::memoization)
      {
        property.enabled = true;
        edge_stack.push(out_edge);
      }
    }
  }

  // Unwrap vertex names
  for (metaprogram::vertex_descriptor vertex : mp->get_vertices()) {
    std::string& name = mp->get_vertex_property(vertex).name;
    if (is_wrap_type(name)) {
      name = trim_copy(name.substr(
          wrap_prefix.size(),
          name.size() - wrap_prefix.size() - wrap_suffix.size()));
      if (!is_template_type(name)) {
        for (metaprogram::edge_descriptor in_edge : mp->get_in_edges(vertex)) {
          mp->get_edge_property(in_edge).kind =
            instantiation_kind::non_template_type;
        }
      }
    }
  }

  // Clang sometimes produces equivalent instantiations events from the same
  // point. Filter out all but one of each
  for (metaprogram::vertex_descriptor vertex : mp->get_vertices()) {

    typedef std::tuple<file_location, instantiation_kind, vertex_descriptor>
      set_element_t;

    std::set<set_element_t> similar_edges;

    for (metaprogram::edge_descriptor edge : mp->get_out_edges(vertex)) {
      metaprogram::edge_property& edge_property =
        mp->get_edge_property(edge);

      set_element_t set_element = std::make_tuple(
            edge_property.point_of_instantiation,
            edge_property.kind,
            mp->get_target(edge));

      auto it = similar_edges.find(set_element);
      if (it != similar_edges.end()) {
        edge_property.enabled = false;
      } else {
        similar_edges.insert(set_element);
      }
    }
  }
}