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(arg_type: eArgTypePath, repetition_type: 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, output_file: file_path.str()))
39 result.SetStatus(eReturnStatusSuccessFinishNoResult);
40 else
41 result.SetStatus(eReturnStatusFailed);
42 }
43};
44
45#define LLDB_OPTIONS_history
46#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(value: option_arg, op: eVarSetOperationAssign);
79 break;
80 case 's':
81 if (option_arg == "end") {
82 m_start_idx.SetCurrentValue(UINT64_MAX);
83 m_start_idx.SetOptionWasSet();
84 } else
85 error = m_start_idx.SetValueFromString(value: option_arg,
86 op: eVarSetOperationAssign);
87 break;
88 case 'e':
89 error =
90 m_stop_idx.SetValueFromString(value: option_arg, op: 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(in_string: "--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 else
172 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(stream&: result.GetOutputStream(), start_idx: start_idx.second,
181 stop_idx: 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(cmd_name: "save",
194 command_obj: CommandObjectSP(new CommandObjectSessionSave(interpreter)));
195 LoadSubCommand(cmd_name: "history",
196 command_obj: CommandObjectSP(new CommandObjectSessionHistory(interpreter)));
197}
198

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of lldb/source/Commands/CommandObjectSession.cpp