data::type_or_error mdb_shell::run_metaprogram(const boost::optional<std::string>& expression, const boost::filesystem::path& output_path_, iface::displayer& displayer_) { const data::result res = _engine.eval( env, expression, output_path_, conf.use_precompiled_headers); if (!res.info.empty()) { displayer_.show_raw_text(res.info); } if (!res.successful) { return data::type_or_error::make_error(res.error); } else if (expression) { return data::type_or_error::make_type(data::type(res.output)); } else { return data::type_or_error::make_none(); } }
std::unique_ptr<iface::event_data_sequence> metaprogram_tracer_clang::eval( iface::environment& env_, const boost::filesystem::path&, const boost::optional<data::cpp_code>& expression_, data::metaprogram_mode mode_, iface::displayer& displayer_) { const auto out = eval_with_templight_dump_on_stdout( env_, expression_, boost::none, _clang_binary); const data::result& res = std::get<0>(out); const std::string& trace = std::get<1>(out); if (!res.info.empty()) { displayer_.show_raw_text(res.info); } if (trace.empty()) { throw exception(res.successful ? "Failed to get template trace" : res.error); } else { return filter_events( yaml_trace( trace, type_or_code_or_error_from_result(res, expression_), expression_ ? *expression_ : data::cpp_code("<environment>"), mode_), determine_from_line( env_.get(), expression_, data::stdin_name_in_clang())); } }
void mdb_shell::command_continue(const std::string& arg, iface::displayer& displayer_) { if (!require_evaluated_metaprogram(displayer_)) { return; } const auto continue_count = parse_defaultable_integer(arg, 1); if (!continue_count) { display_argument_parsing_failed(displayer_); return; } direction_t direction = *continue_count >= 0 ? direction_t::forward : direction_t::backwards; const breakpoint* breakpoint_ptr = nullptr; for (int i = 0; i < std::abs(*continue_count) && !mp->is_at_endpoint(direction); ++i) { breakpoint_ptr = continue_metaprogram(direction); } if (breakpoint_ptr) { displayer_.show_raw_text(breakpoint_ptr->to_string() + " reached"); } display_movement_info(*continue_count != 0, displayer_); }
void mdb_shell::command_rbreak(const std::string& arg, iface::displayer& displayer_) { if (arg.empty()) { displayer_.show_error("Argument expected"); return; } if (!require_evaluated_metaprogram(displayer_)) { return; } try { breakpoint bp{next_breakpoint_id, boost::regex(arg)}; ++next_breakpoint_id; unsigned match_count = 0; for (metaprogram::vertex_descriptor vertex : mp->get_vertices()) { if (bp.match(mp->get_vertex_property(vertex).type)) { match_count += mp->get_traversal_count(vertex); } } if (match_count == 0) { displayer_.show_raw_text("Breakpoint \"" + arg + "\" will never stop the execution"); } else { displayer_.show_raw_text( "Breakpoint \"" + arg + "\" will stop the execution on " + std::to_string(match_count) + (match_count > 1 ? " locations" : " location")); breakpoints.push_back(bp); } } catch (const boost::regex_error&) { displayer_.show_error("\"" + arg + "\" is not a valid regex"); } }
void mdb_shell::command_help(const std::string& arg, iface::displayer& displayer_) { if (arg.empty()) { displayer_.show_raw_text("List of available commands:"); displayer_.show_raw_text(""); for (const mdb_command& cmd : command_handler.get_commands()) { displayer_.show_raw_text(cmd.get_keys().front() + " -- " + cmd.get_short_description()); } displayer_.show_raw_text(""); displayer_.show_raw_text( "Type \"help\" followed by a command name for more information."); displayer_.show_raw_text( "Command name abbreviations are allowed if unambiguous."); displayer_.show_raw_text( "A blank line as an input will repeat the last command," " if it makes sense."); return; } auto command_arg_pair = command_handler.get_command_for_line(arg); if (!command_arg_pair) { displayer_.show_error("Command not found\n"); return; } using boost::algorithm::join; mdb_command cmd; std::string command_args; std::tie(cmd, command_args) = *command_arg_pair; if (!command_args.empty()) { displayer_.show_error("Only one argument expected\n"); return; } displayer_.show_raw_text(join(cmd.get_keys(), "|") + " " + cmd.get_usage()); displayer_.show_raw_text(cmd.get_full_description()); }
void mdb_shell::command_break(const std::string& arg, iface::displayer& displayer_) { // TODO there will other more kinds of arguments here but needs a proper but // it needs a proper command parser if (arg != "list") { displayer_.show_error("Call break like this: \"break list\""); return; } if (breakpoints.empty()) { displayer_.show_raw_text("No breakpoints currently set"); return; } for (const breakpoint& bp : breakpoints) { displayer_.show_raw_text(bp.to_string()); } }
void mdb_shell::command_evaluate(const std::string& arg_copy, iface::displayer& displayer_) { // Easier not to use spirit here (or probably not...) // TODO OK. after -profile, this parsing really needs some refactoring std::string arg = arg_copy; const std::string full_flag = "-full"; const std::string profile_flag = "-profile"; bool has_full = false; bool has_profile = false; // Intentionally left really ugly for more motivation to refactor while (true) { if (boost::starts_with(arg, full_flag) && (arg.size() == full_flag.size() || std::isspace(arg[full_flag.size()]))) { has_full = true; arg = boost::trim_left_copy(arg.substr(full_flag.size())); } else if (boost::starts_with(arg, profile_flag) && (arg.size() == profile_flag.size() || std::isspace(arg[profile_flag.size()]))) { has_profile = true; arg = boost::trim_left_copy(arg.substr(profile_flag.size())); } else { break; } } if (has_full && has_profile) { displayer_.show_error( "-full and -profile flags cannot be used together."); return; } boost::optional<std::string> expression = arg; if (expression->empty()) { if (!mp) { displayer_.show_error("Nothing has been evaluated yet."); return; } expression = last_evaluated_expression; } else if (*expression == "-") { expression = boost::none; } next_breakpoint_id = 1; breakpoints.clear(); metaprogram::mode_t mode = [&] { if (has_full) { return metaprogram::mode_t::full; } if (has_profile) { return metaprogram::mode_t::profile; } return metaprogram::mode_t::normal; }(); last_evaluated_expression = expression; if (!run_metaprogram_with_templight(expression, mode, displayer_)) { return; } displayer_.show_raw_text("Metaprogram started"); filter_metaprogram(bool(expression)); }
void mdb_shell::display_metaprogram_finished(iface::displayer& displayer_) const { displayer_.show_raw_text("Metaprogram finished"); displayer_.show_type_or_error(mp->get_evaluation_result()); }
void mdb_shell::display_metaprogram_reached_the_beginning( iface::displayer& displayer_) const { displayer_.show_raw_text("Metaprogram reached the beginning"); }