示例#1
0
  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()));
    }
  }
示例#3
0
  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_);
  }
示例#4
0
  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");
    }
  }
示例#5
0
  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());
  }
示例#6
0
  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());
    }
  }
示例#7
0
  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));
  }
示例#8
0
 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());
 }
示例#9
0
 void mdb_shell::display_metaprogram_reached_the_beginning(
     iface::displayer& displayer_) const
 {
   displayer_.show_raw_text("Metaprogram reached the beginning");
 }