brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.1 KiB · ac7eec5 Raw
198 lines · cpp
1#include "CommandObjectSession.h"2#include "lldb/Host/OptionParser.h"3#include "lldb/Interpreter/CommandInterpreter.h"4#include "lldb/Interpreter/CommandOptionArgumentTable.h"5#include "lldb/Interpreter/CommandReturnObject.h"6#include "lldb/Interpreter/OptionArgParser.h"7#include "lldb/Interpreter/OptionValue.h"8#include "lldb/Interpreter/OptionValueBoolean.h"9#include "lldb/Interpreter/OptionValueString.h"10#include "lldb/Interpreter/OptionValueUInt64.h"11#include "lldb/Interpreter/Options.h"12 13using namespace lldb;14using namespace lldb_private;15 16class CommandObjectSessionSave : public CommandObjectParsed {17public:18  CommandObjectSessionSave(CommandInterpreter &interpreter)19      : CommandObjectParsed(interpreter, "session save",20                            "Save the current session transcripts to a file.\n"21                            "If no file if specified, transcripts will be "22                            "saved to a temporary file.\n"23                            "Note: transcripts will only be saved if "24                            "interpreter.save-transcript is true.\n",25                            "session save [file]") {26    AddSimpleArgumentList(eArgTypePath, eArgRepeatOptional);27  }28 29  ~CommandObjectSessionSave() override = default;30 31protected:32  void DoExecute(Args &args, CommandReturnObject &result) override {33    llvm::StringRef file_path;34 35    if (!args.empty())36      file_path = args[0].ref();37 38    if (m_interpreter.SaveTranscript(result, file_path.str()))39      result.SetStatus(eReturnStatusSuccessFinishNoResult);40    else41      result.SetStatus(eReturnStatusFailed);42  }43};44 45#define LLDB_OPTIONS_history46#include "CommandOptions.inc"47 48class CommandObjectSessionHistory : public CommandObjectParsed {49public:50  CommandObjectSessionHistory(CommandInterpreter &interpreter)51      : CommandObjectParsed(interpreter, "session history",52                            "Dump the history of commands in this session.\n"53                            "Commands in the history list can be run again "54                            "using \"!<INDEX>\".   \"!-<OFFSET>\" will re-run "55                            "the command that is <OFFSET> commands from the end"56                            " of the list (counting the current command).",57                            nullptr) {}58 59  ~CommandObjectSessionHistory() override = default;60 61  Options *GetOptions() override { return &m_options; }62 63protected:64  class CommandOptions : public Options {65  public:66    CommandOptions()67        : m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {}68 69    ~CommandOptions() override = default;70 71    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,72                          ExecutionContext *execution_context) override {73      Status error;74      const int short_option = m_getopt_table[option_idx].val;75 76      switch (short_option) {77      case 'c':78        error = m_count.SetValueFromString(option_arg, eVarSetOperationAssign);79        break;80      case 's':81        if (option_arg == "end") {82          m_start_idx.SetCurrentValue(UINT64_MAX);83          m_start_idx.SetOptionWasSet();84        } else85          error = m_start_idx.SetValueFromString(option_arg,86                                                 eVarSetOperationAssign);87        break;88      case 'e':89        error =90            m_stop_idx.SetValueFromString(option_arg, eVarSetOperationAssign);91        break;92      case 'C':93        m_clear.SetCurrentValue(true);94        m_clear.SetOptionWasSet();95        break;96      default:97        llvm_unreachable("Unimplemented option");98      }99 100      return error;101    }102 103    void OptionParsingStarting(ExecutionContext *execution_context) override {104      m_start_idx.Clear();105      m_stop_idx.Clear();106      m_count.Clear();107      m_clear.Clear();108    }109 110    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {111      return llvm::ArrayRef(g_history_options);112    }113 114    // Instance variables to hold the values for command options.115 116    OptionValueUInt64 m_start_idx;117    OptionValueUInt64 m_stop_idx;118    OptionValueUInt64 m_count;119    OptionValueBoolean m_clear;120  };121 122  void DoExecute(Args &command, CommandReturnObject &result) override {123    if (m_options.m_clear.GetCurrentValue() &&124        m_options.m_clear.OptionWasSet()) {125      m_interpreter.GetCommandHistory().Clear();126      result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);127    } else {128      if (m_options.m_start_idx.OptionWasSet() &&129          m_options.m_stop_idx.OptionWasSet() &&130          m_options.m_count.OptionWasSet()) {131        result.AppendError("--count, --start-index and --end-index cannot be "132                           "all specified in the same invocation");133        result.SetStatus(lldb::eReturnStatusFailed);134      } else {135        std::pair<bool, uint64_t> start_idx(136            m_options.m_start_idx.OptionWasSet(),137            m_options.m_start_idx.GetCurrentValue());138        std::pair<bool, uint64_t> stop_idx(139            m_options.m_stop_idx.OptionWasSet(),140            m_options.m_stop_idx.GetCurrentValue());141        std::pair<bool, uint64_t> count(m_options.m_count.OptionWasSet(),142                                        m_options.m_count.GetCurrentValue());143 144        const CommandHistory &history(m_interpreter.GetCommandHistory());145 146        if (start_idx.first && start_idx.second == UINT64_MAX) {147          if (count.first) {148            start_idx.second = history.GetSize() - count.second;149            stop_idx.second = history.GetSize() - 1;150          } else if (stop_idx.first) {151            start_idx.second = stop_idx.second;152            stop_idx.second = history.GetSize() - 1;153          } else {154            start_idx.second = 0;155            stop_idx.second = history.GetSize() - 1;156          }157        } else {158          if (!start_idx.first && !stop_idx.first && !count.first) {159            start_idx.second = 0;160            stop_idx.second = history.GetSize() - 1;161          } else if (start_idx.first) {162            if (count.first) {163              stop_idx.second = start_idx.second + count.second - 1;164            } else if (!stop_idx.first) {165              stop_idx.second = history.GetSize() - 1;166            }167          } else if (stop_idx.first) {168            if (count.first) {169              if (stop_idx.second >= count.second)170                start_idx.second = stop_idx.second - count.second + 1;171              else172                start_idx.second = 0;173            }174          } else /* if (count.first) */175          {176            start_idx.second = 0;177            stop_idx.second = count.second - 1;178          }179        }180        history.Dump(result.GetOutputStream(), start_idx.second,181                     stop_idx.second);182      }183    }184  }185 186  CommandOptions m_options;187};188 189CommandObjectSession::CommandObjectSession(CommandInterpreter &interpreter)190    : CommandObjectMultiword(interpreter, "session",191                             "Commands controlling LLDB session.",192                             "session <subcommand> [<command-options>]") {193  LoadSubCommand("save",194                 CommandObjectSP(new CommandObjectSessionSave(interpreter)));195  LoadSubCommand("history",196                 CommandObjectSP(new CommandObjectSessionHistory(interpreter)));197}198