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; } } } }
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); } } } }