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