Path: blob/main/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp
39587 views
#include "CommandObjectSession.h"1#include "lldb/Host/OptionParser.h"2#include "lldb/Interpreter/CommandInterpreter.h"3#include "lldb/Interpreter/CommandOptionArgumentTable.h"4#include "lldb/Interpreter/CommandReturnObject.h"5#include "lldb/Interpreter/OptionArgParser.h"6#include "lldb/Interpreter/OptionValue.h"7#include "lldb/Interpreter/OptionValueBoolean.h"8#include "lldb/Interpreter/OptionValueString.h"9#include "lldb/Interpreter/OptionValueUInt64.h"10#include "lldb/Interpreter/Options.h"1112using namespace lldb;13using namespace lldb_private;1415class CommandObjectSessionSave : public CommandObjectParsed {16public:17CommandObjectSessionSave(CommandInterpreter &interpreter)18: CommandObjectParsed(interpreter, "session save",19"Save the current session transcripts to a file.\n"20"If no file if specified, transcripts will be "21"saved to a temporary file.",22"session save [file]") {23AddSimpleArgumentList(eArgTypePath, eArgRepeatOptional);24}2526~CommandObjectSessionSave() override = default;2728protected:29void DoExecute(Args &args, CommandReturnObject &result) override {30llvm::StringRef file_path;3132if (!args.empty())33file_path = args[0].ref();3435if (m_interpreter.SaveTranscript(result, file_path.str()))36result.SetStatus(eReturnStatusSuccessFinishNoResult);37else38result.SetStatus(eReturnStatusFailed);39}40};4142#define LLDB_OPTIONS_history43#include "CommandOptions.inc"4445class CommandObjectSessionHistory : public CommandObjectParsed {46public:47CommandObjectSessionHistory(CommandInterpreter &interpreter)48: CommandObjectParsed(interpreter, "session history",49"Dump the history of commands in this session.\n"50"Commands in the history list can be run again "51"using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "52"the command that is <OFFSET> commands from the end"53" of the list (counting the current command).",54nullptr) {}5556~CommandObjectSessionHistory() override = default;5758Options *GetOptions() override { return &m_options; }5960protected:61class CommandOptions : public Options {62public:63CommandOptions()64: m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {}6566~CommandOptions() override = default;6768Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,69ExecutionContext *execution_context) override {70Status error;71const int short_option = m_getopt_table[option_idx].val;7273switch (short_option) {74case 'c':75error = m_count.SetValueFromString(option_arg, eVarSetOperationAssign);76break;77case 's':78if (option_arg == "end") {79m_start_idx.SetCurrentValue(UINT64_MAX);80m_start_idx.SetOptionWasSet();81} else82error = m_start_idx.SetValueFromString(option_arg,83eVarSetOperationAssign);84break;85case 'e':86error =87m_stop_idx.SetValueFromString(option_arg, eVarSetOperationAssign);88break;89case 'C':90m_clear.SetCurrentValue(true);91m_clear.SetOptionWasSet();92break;93default:94llvm_unreachable("Unimplemented option");95}9697return error;98}99100void OptionParsingStarting(ExecutionContext *execution_context) override {101m_start_idx.Clear();102m_stop_idx.Clear();103m_count.Clear();104m_clear.Clear();105}106107llvm::ArrayRef<OptionDefinition> GetDefinitions() override {108return llvm::ArrayRef(g_history_options);109}110111// Instance variables to hold the values for command options.112113OptionValueUInt64 m_start_idx;114OptionValueUInt64 m_stop_idx;115OptionValueUInt64 m_count;116OptionValueBoolean m_clear;117};118119void DoExecute(Args &command, CommandReturnObject &result) override {120if (m_options.m_clear.GetCurrentValue() &&121m_options.m_clear.OptionWasSet()) {122m_interpreter.GetCommandHistory().Clear();123result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);124} else {125if (m_options.m_start_idx.OptionWasSet() &&126m_options.m_stop_idx.OptionWasSet() &&127m_options.m_count.OptionWasSet()) {128result.AppendError("--count, --start-index and --end-index cannot be "129"all specified in the same invocation");130result.SetStatus(lldb::eReturnStatusFailed);131} else {132std::pair<bool, uint64_t> start_idx(133m_options.m_start_idx.OptionWasSet(),134m_options.m_start_idx.GetCurrentValue());135std::pair<bool, uint64_t> stop_idx(136m_options.m_stop_idx.OptionWasSet(),137m_options.m_stop_idx.GetCurrentValue());138std::pair<bool, uint64_t> count(m_options.m_count.OptionWasSet(),139m_options.m_count.GetCurrentValue());140141const CommandHistory &history(m_interpreter.GetCommandHistory());142143if (start_idx.first && start_idx.second == UINT64_MAX) {144if (count.first) {145start_idx.second = history.GetSize() - count.second;146stop_idx.second = history.GetSize() - 1;147} else if (stop_idx.first) {148start_idx.second = stop_idx.second;149stop_idx.second = history.GetSize() - 1;150} else {151start_idx.second = 0;152stop_idx.second = history.GetSize() - 1;153}154} else {155if (!start_idx.first && !stop_idx.first && !count.first) {156start_idx.second = 0;157stop_idx.second = history.GetSize() - 1;158} else if (start_idx.first) {159if (count.first) {160stop_idx.second = start_idx.second + count.second - 1;161} else if (!stop_idx.first) {162stop_idx.second = history.GetSize() - 1;163}164} else if (stop_idx.first) {165if (count.first) {166if (stop_idx.second >= count.second)167start_idx.second = stop_idx.second - count.second + 1;168else169start_idx.second = 0;170}171} else /* if (count.first) */172{173start_idx.second = 0;174stop_idx.second = count.second - 1;175}176}177history.Dump(result.GetOutputStream(), start_idx.second,178stop_idx.second);179}180}181}182183CommandOptions m_options;184};185186CommandObjectSession::CommandObjectSession(CommandInterpreter &interpreter)187: CommandObjectMultiword(interpreter, "session",188"Commands controlling LLDB session.",189"session <subcommand> [<command-options>]") {190LoadSubCommand("save",191CommandObjectSP(new CommandObjectSessionSave(interpreter)));192LoadSubCommand("history",193CommandObjectSP(new CommandObjectSessionHistory(interpreter)));194}195196197