void pragma_environment_save::run(const data::command::iterator&,
                                  const data::command::iterator&,
                                  const data::command::iterator& args_begin_,
                                  const data::command::iterator& args_end_,
                                  iface::displayer& displayer_) const
{
    if (_config.saving_enabled)
    {
        const std::string fn =
            boost::algorithm::trim_copy(tokens_to_string(args_begin_, args_end_));

        if (fn.empty())
        {
            displayer_.show_error(
                "Filename to save the environment into is missing.");
        }
        else
        {
            std::ofstream f(fn.c_str());
            f << _env.get_all() << std::endl;
            if (f.fail() || f.bad())
            {
                displayer_.show_error("Failed to save the environment into file " + fn);
            }
        }
    }
    else
    {
        displayer_.show_error(
            "Saving is disabled by the --disable_saving command line argument.");
    }
}
Пример #2
0
  void mdb_shell::line_available(const std::string& line_arg,
                                 iface::displayer& displayer_,
                                 iface::history& history_)
  {

    try
    {
      using boost::algorithm::all;
      using boost::is_space;

      std::string line = line_arg;

      if (line != prev_line && !line.empty())
      {
        history_.add(line);
      }

      if (line.empty())
      {
        if (!last_command_repeatable)
        {
          return;
        }
        line = prev_line;
      }
      else
      {
        prev_line = line;
      }

      if (all(line, is_space()))
      {
        return;
      }

      auto command_arg_pair = command_handler.get_command_for_line(line);
      if (!command_arg_pair)
      {
        displayer_.show_error("Command parsing failed\n");
        last_command_repeatable = false;
        return;
      }

      mdb_command cmd;
      std::string args;
      std::tie(cmd, args) = *command_arg_pair;

      last_command_repeatable = cmd.is_repeatable();

      cmd.get_func()(*this, args, displayer_);
    }
    catch (const std::exception& ex)
    {
      displayer_.show_error(std::string("Error: ") + ex.what() + "\n");
    }
    catch (...)
    {
      displayer_.show_error("Unknown error\n");
    }
  }
Пример #3
0
void pragma_switch::run(const data::command::iterator&,
                        const data::command::iterator&,
                        const data::command::iterator& args_begin_,
                        const data::command::iterator& args_end_,
                        iface::displayer& displayer_) const
{
  auto i = args_begin_;

  if (i != args_end_)
  {
    const std::string v = i->value().value();
    if (valid_argument(v))
    {
      ++i;
      if (i == args_end_)
      {
        _update(element_of(true_values, v));
      }
      else
      {
        displayer_.show_error("Invalid arguments after " + v + ": " +
                              tokens_to_string(i, args_end_).value());
      }
    }
    else
    {
      displayer_.show_error("Invalid argument " + v + ". Valid values are: " +
                            valid_arguments());
    }
  }
  displayer_.show_comment(
      data::text(_name + " is " + (_query() ? "on" : "off")));
}
Пример #4
0
  void mdb_shell::command_frame(const std::string& arg,
                                iface::displayer& displayer_)
  {
    if (!require_running_or_errored_metaprogram(displayer_))
    {
      return;
    }

    const auto frame_index = parse_mandatory_integer(arg);
    if (!frame_index)
    {
      display_argument_parsing_failed(displayer_);
      return;
    }

    auto backtrace = mp->get_backtrace();

    if (frame_index < 0 || *frame_index >= static_cast<int>(backtrace.size()))
    {
      displayer_.show_error("Frame index out of range");
      return;
    }

    display_frame(backtrace[*frame_index], displayer_);
  }
Пример #5
0
  bool mdb_shell::run_metaprogram_with_templight(
      const boost::optional<std::string>& expression,
      metaprogram::mode_t mode,
      iface::displayer& displayer_)
  {
    const boost::filesystem::path output_path = _mdb_temp_dir / "templight.pb";

    data::type_or_error evaluation_result =
        run_metaprogram(expression, output_path, displayer_);

    // Opening in binary mode, because some platforms interpret some characters
    // specially in text mode, which caused parsing to fail.
    std::ifstream protobuf_stream(output_path.string() + ".trace.pbf",
                                  std::ios_base::in | std::ios_base::binary);

    if (!protobuf_stream)
    {
      if (evaluation_result.is_error())
      {
        displayer_.show_error(evaluation_result.get_error());
      }
      else
      {
        // Shouldn't happen
        displayer_.show_error("Unexpected type type_or_error result");
      }
      mp = boost::none;
      return false;
    }

    mp = metaprogram::create_from_protobuf_stream(
        protobuf_stream, mode, expression ? *expression : "<environment>",
        data::file_location{}, // TODO something sensible here?
        evaluation_result);

    assert(mp);
    if (mp->is_empty() && evaluation_result.is_error())
    {
      // Most errors will cause templight to generate an empty trace
      // We're only intrested in non-empty traces
      displayer_.show_error(evaluation_result.get_error());
      mp = boost::none;
      return false;
    }

    return true;
  }
Пример #6
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());
  }
Пример #7
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");
    }
  }
Пример #8
0
 bool
 mdb_shell::require_evaluated_metaprogram(iface::displayer& displayer_) const
 {
   if (!mp)
   {
     displayer_.show_error("Metaprogram not evaluated yet");
     return false;
   }
   return true;
 }
Пример #9
0
 bool mdb_shell::require_empty_args(const std::string& args,
                                    iface::displayer& displayer_) const
 {
   if (!args.empty())
   {
     displayer_.show_error("This command doesn't accept arguments");
     return false;
   }
   return true;
 }
Пример #10
0
  void pragma_config_load::run(const data::command::iterator&,
                               const data::command::iterator&,
                               const data::command::iterator& args_begin_,
                               const data::command::iterator& args_end_,
                               iface::displayer& displayer_) const
  {
    const data::shell_config_name name = data::shell_config_name(
        tokens_to_string(args_begin_, args_end_).value());

    const auto& configs = _shell.get_config().shell_configs();

    const auto cfg = std::find_if(
        configs.begin(), configs.end(),
        [&name](const data::shell_config& cfg_) { return cfg_.name == name; });

    if (cfg == configs.end())
    {
      throw exception("Config " + name + " not found.");
    }
    else
    {
      const auto old_config = _shell.get_config().active_shell_config().name;
      _shell.get_config().activate(name);
      try
      {
        _shell.rebuild_environment();
        displayer_.show_comment(data::text("Switched to config " + name));
      }
      catch (const std::exception& e)
      {
        displayer_.show_error("Error loading config " + name + ": " + e.what());
        restore_config(old_config, _shell);
      }
      catch (...)
      {
        displayer_.show_error("Error loading config " + name +
                              ": unknown exception");
        restore_config(old_config, _shell);
      }
    }
  }
Пример #11
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());
    }
  }
Пример #12
0
void pragma_help::run(const data::command::iterator&,
                      const data::command::iterator&,
                      const data::command::iterator& args_begin_,
                      const data::command::iterator& args_end_,
                      iface::displayer& displayer_) const
{
  using boost::algorithm::join;

  if (args_begin_ == args_end_)
  {
    display_all(displayer_, _pragma_handlers);
  }
  else
  {
    std::vector<std::string> args;
    for (auto i = args_begin_; i != args_end_; ++i)
    {
      switch (i->category())
      {
      case data::token_category::whitespace:
      case data::token_category::comment:
        // skip token
        break;
      default:
        args.push_back(i->value().value());
      }
    }

    data::text help_text;
    bool was_pragma = false;

    for (const auto& h : _pragma_handlers)
    {
      if (prefix_of(args.begin(), args.end(), h.first.begin(), h.first.end()))
      {
        if (was_pragma)
        {
          help_text.paragraphs.push_back(data::paragraph(""));
        }
        else
        {
          was_pragma = true;
        }
        const std::string p_args = h.second.arguments();
        help_text.paragraphs.push_back(
            data::paragraph("#msh " + join(h.first, " ") +
                            (p_args.empty() ? std::string() : " " + p_args)));
        help_text.paragraphs.push_back(
            data::paragraph(h.second.description(), "    "));
      }
    }
    if (was_pragma)
    {
      displayer_.show_comment(help_text);
    }
    else
    {
      displayer_.show_error("Pragma " + join(args, " ") + " not found.");
    }
  }
}
Пример #13
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));
  }
Пример #14
0
 void
 mdb_shell::display_argument_parsing_failed(iface::displayer& displayer_) const
 {
   displayer_.show_error("Argument parsing failed");
 }