1 //===-- SBCommandInterpreter.cpp ------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/lldb-types.h"
10
11 #include "lldb/Interpreter/CommandInterpreter.h"
12 #include "lldb/Interpreter/CommandObjectMultiword.h"
13 #include "lldb/Interpreter/CommandReturnObject.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Utility/Instrumentation.h"
16 #include "lldb/Utility/Listener.h"
17
18 #include "lldb/API/SBBroadcaster.h"
19 #include "lldb/API/SBCommandInterpreter.h"
20 #include "lldb/API/SBCommandInterpreterRunOptions.h"
21 #include "lldb/API/SBCommandReturnObject.h"
22 #include "lldb/API/SBEvent.h"
23 #include "lldb/API/SBExecutionContext.h"
24 #include "lldb/API/SBListener.h"
25 #include "lldb/API/SBProcess.h"
26 #include "lldb/API/SBStream.h"
27 #include "lldb/API/SBStringList.h"
28 #include "lldb/API/SBTarget.h"
29
30 #include <memory>
31 #include <optional>
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 class CommandPluginInterfaceImplementation : public CommandObjectParsed {
37 public:
CommandPluginInterfaceImplementation(CommandInterpreter & interpreter,const char * name,lldb::SBCommandPluginInterface * backend,const char * help=nullptr,const char * syntax=nullptr,uint32_t flags=0,const char * auto_repeat_command="")38 CommandPluginInterfaceImplementation(CommandInterpreter &interpreter,
39 const char *name,
40 lldb::SBCommandPluginInterface *backend,
41 const char *help = nullptr,
42 const char *syntax = nullptr,
43 uint32_t flags = 0,
44 const char *auto_repeat_command = "")
45 : CommandObjectParsed(interpreter, name, help, syntax, flags),
46 m_backend(backend) {
47 m_auto_repeat_command =
48 auto_repeat_command == nullptr
49 ? std::nullopt
50 : std::optional<std::string>(auto_repeat_command);
51 // We don't know whether any given command coming from this interface takes
52 // arguments or not so here we're just disabling the basic args check.
53 CommandArgumentData none_arg{eArgTypeNone, eArgRepeatStar};
54 m_arguments.push_back({none_arg});
55 }
56
IsRemovable() const57 bool IsRemovable() const override { return true; }
58
59 /// More documentation is available in lldb::CommandObject::GetRepeatCommand,
60 /// but in short, if std::nullopt is returned, the previous command will be
61 /// repeated, and if an empty string is returned, no commands will be
62 /// executed.
GetRepeatCommand(Args & current_command_args,uint32_t index)63 std::optional<std::string> GetRepeatCommand(Args ¤t_command_args,
64 uint32_t index) override {
65 if (!m_auto_repeat_command)
66 return std::nullopt;
67 else
68 return m_auto_repeat_command;
69 }
70
71 protected:
DoExecute(Args & command,CommandReturnObject & result)72 bool DoExecute(Args &command, CommandReturnObject &result) override {
73 SBCommandReturnObject sb_return(result);
74 SBCommandInterpreter sb_interpreter(&m_interpreter);
75 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
76 bool ret = m_backend->DoExecute(
77 debugger_sb, command.GetArgumentVector(), sb_return);
78 return ret;
79 }
80 std::shared_ptr<lldb::SBCommandPluginInterface> m_backend;
81 std::optional<std::string> m_auto_repeat_command;
82 };
83
SBCommandInterpreter(CommandInterpreter * interpreter)84 SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter)
85 : m_opaque_ptr(interpreter) {
86 LLDB_INSTRUMENT_VA(this, interpreter);
87 }
88
SBCommandInterpreter(const SBCommandInterpreter & rhs)89 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs)
90 : m_opaque_ptr(rhs.m_opaque_ptr) {
91 LLDB_INSTRUMENT_VA(this, rhs);
92 }
93
94 SBCommandInterpreter::~SBCommandInterpreter() = default;
95
96 const SBCommandInterpreter &SBCommandInterpreter::
operator =(const SBCommandInterpreter & rhs)97 operator=(const SBCommandInterpreter &rhs) {
98 LLDB_INSTRUMENT_VA(this, rhs);
99
100 m_opaque_ptr = rhs.m_opaque_ptr;
101 return *this;
102 }
103
IsValid() const104 bool SBCommandInterpreter::IsValid() const {
105 LLDB_INSTRUMENT_VA(this);
106 return this->operator bool();
107 }
operator bool() const108 SBCommandInterpreter::operator bool() const {
109 LLDB_INSTRUMENT_VA(this);
110
111 return m_opaque_ptr != nullptr;
112 }
113
CommandExists(const char * cmd)114 bool SBCommandInterpreter::CommandExists(const char *cmd) {
115 LLDB_INSTRUMENT_VA(this, cmd);
116
117 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd)
118 : false);
119 }
120
AliasExists(const char * cmd)121 bool SBCommandInterpreter::AliasExists(const char *cmd) {
122 LLDB_INSTRUMENT_VA(this, cmd);
123
124 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd)
125 : false);
126 }
127
IsActive()128 bool SBCommandInterpreter::IsActive() {
129 LLDB_INSTRUMENT_VA(this);
130
131 return (IsValid() ? m_opaque_ptr->IsActive() : false);
132 }
133
WasInterrupted() const134 bool SBCommandInterpreter::WasInterrupted() const {
135 LLDB_INSTRUMENT_VA(this);
136
137 return (IsValid() ? m_opaque_ptr->WasInterrupted() : false);
138 }
139
GetIOHandlerControlSequence(char ch)140 const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) {
141 LLDB_INSTRUMENT_VA(this, ch);
142
143 return (IsValid()
144 ? m_opaque_ptr->GetDebugger()
145 .GetTopIOHandlerControlSequence(ch)
146 .GetCString()
147 : nullptr);
148 }
149
150 lldb::ReturnStatus
HandleCommand(const char * command_line,SBCommandReturnObject & result,bool add_to_history)151 SBCommandInterpreter::HandleCommand(const char *command_line,
152 SBCommandReturnObject &result,
153 bool add_to_history) {
154 LLDB_INSTRUMENT_VA(this, command_line, result, add_to_history);
155
156 SBExecutionContext sb_exe_ctx;
157 return HandleCommand(command_line, sb_exe_ctx, result, add_to_history);
158 }
159
HandleCommand(const char * command_line,SBExecutionContext & override_context,SBCommandReturnObject & result,bool add_to_history)160 lldb::ReturnStatus SBCommandInterpreter::HandleCommand(
161 const char *command_line, SBExecutionContext &override_context,
162 SBCommandReturnObject &result, bool add_to_history) {
163 LLDB_INSTRUMENT_VA(this, command_line, override_context, result,
164 add_to_history);
165
166 result.Clear();
167 if (command_line && IsValid()) {
168 result.ref().SetInteractive(false);
169 auto do_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
170 if (override_context.get())
171 m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
172 override_context.get()->Lock(true),
173 result.ref());
174 else
175 m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
176 result.ref());
177 } else {
178 result->AppendError(
179 "SBCommandInterpreter or the command line is not valid");
180 }
181
182 return result.GetStatus();
183 }
184
HandleCommandsFromFile(lldb::SBFileSpec & file,lldb::SBExecutionContext & override_context,lldb::SBCommandInterpreterRunOptions & options,lldb::SBCommandReturnObject result)185 void SBCommandInterpreter::HandleCommandsFromFile(
186 lldb::SBFileSpec &file, lldb::SBExecutionContext &override_context,
187 lldb::SBCommandInterpreterRunOptions &options,
188 lldb::SBCommandReturnObject result) {
189 LLDB_INSTRUMENT_VA(this, file, override_context, options, result);
190
191 if (!IsValid()) {
192 result->AppendError("SBCommandInterpreter is not valid.");
193 return;
194 }
195
196 if (!file.IsValid()) {
197 SBStream s;
198 file.GetDescription(s);
199 result->AppendErrorWithFormat("File is not valid: %s.", s.GetData());
200 }
201
202 FileSpec tmp_spec = file.ref();
203 if (override_context.get())
204 m_opaque_ptr->HandleCommandsFromFile(tmp_spec,
205 override_context.get()->Lock(true),
206 options.ref(),
207 result.ref());
208
209 else
210 m_opaque_ptr->HandleCommandsFromFile(tmp_spec, options.ref(), result.ref());
211 }
212
HandleCompletion(const char * current_line,const char * cursor,const char * last_char,int match_start_point,int max_return_elements,SBStringList & matches)213 int SBCommandInterpreter::HandleCompletion(
214 const char *current_line, const char *cursor, const char *last_char,
215 int match_start_point, int max_return_elements, SBStringList &matches) {
216 LLDB_INSTRUMENT_VA(this, current_line, cursor, last_char, match_start_point,
217 max_return_elements, matches);
218
219 SBStringList dummy_descriptions;
220 return HandleCompletionWithDescriptions(
221 current_line, cursor, last_char, match_start_point, max_return_elements,
222 matches, dummy_descriptions);
223 }
224
HandleCompletionWithDescriptions(const char * current_line,const char * cursor,const char * last_char,int match_start_point,int max_return_elements,SBStringList & matches,SBStringList & descriptions)225 int SBCommandInterpreter::HandleCompletionWithDescriptions(
226 const char *current_line, const char *cursor, const char *last_char,
227 int match_start_point, int max_return_elements, SBStringList &matches,
228 SBStringList &descriptions) {
229 LLDB_INSTRUMENT_VA(this, current_line, cursor, last_char, match_start_point,
230 max_return_elements, matches, descriptions);
231
232 // Sanity check the arguments that are passed in: cursor & last_char have to
233 // be within the current_line.
234 if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
235 return 0;
236
237 if (cursor < current_line || last_char < current_line)
238 return 0;
239
240 size_t current_line_size = strlen(current_line);
241 if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) ||
242 last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
243 return 0;
244
245 if (!IsValid())
246 return 0;
247
248 lldb_private::StringList lldb_matches, lldb_descriptions;
249 CompletionResult result;
250 CompletionRequest request(current_line, cursor - current_line, result);
251 m_opaque_ptr->HandleCompletion(request);
252 result.GetMatches(lldb_matches);
253 result.GetDescriptions(lldb_descriptions);
254
255 // Make the result array indexed from 1 again by adding the 'common prefix'
256 // of all completions as element 0. This is done to emulate the old API.
257 if (request.GetParsedLine().GetArgumentCount() == 0) {
258 // If we got an empty string, insert nothing.
259 lldb_matches.InsertStringAtIndex(0, "");
260 lldb_descriptions.InsertStringAtIndex(0, "");
261 } else {
262 // Now figure out if there is a common substring, and if so put that in
263 // element 0, otherwise put an empty string in element 0.
264 std::string command_partial_str = request.GetCursorArgumentPrefix().str();
265
266 std::string common_prefix = lldb_matches.LongestCommonPrefix();
267 const size_t partial_name_len = command_partial_str.size();
268 common_prefix.erase(0, partial_name_len);
269
270 // If we matched a unique single command, add a space... Only do this if
271 // the completer told us this was a complete word, however...
272 if (lldb_matches.GetSize() == 1) {
273 char quote_char = request.GetParsedArg().GetQuoteChar();
274 common_prefix =
275 Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
276 if (request.GetParsedArg().IsQuoted())
277 common_prefix.push_back(quote_char);
278 common_prefix.push_back(' ');
279 }
280 lldb_matches.InsertStringAtIndex(0, common_prefix.c_str());
281 lldb_descriptions.InsertStringAtIndex(0, "");
282 }
283
284 SBStringList temp_matches_list(&lldb_matches);
285 matches.AppendList(temp_matches_list);
286 SBStringList temp_descriptions_list(&lldb_descriptions);
287 descriptions.AppendList(temp_descriptions_list);
288 return result.GetNumberOfResults();
289 }
290
HandleCompletionWithDescriptions(const char * current_line,uint32_t cursor_pos,int match_start_point,int max_return_elements,SBStringList & matches,SBStringList & descriptions)291 int SBCommandInterpreter::HandleCompletionWithDescriptions(
292 const char *current_line, uint32_t cursor_pos, int match_start_point,
293 int max_return_elements, SBStringList &matches,
294 SBStringList &descriptions) {
295 LLDB_INSTRUMENT_VA(this, current_line, cursor_pos, match_start_point,
296 max_return_elements, matches, descriptions);
297
298 const char *cursor = current_line + cursor_pos;
299 const char *last_char = current_line + strlen(current_line);
300 return HandleCompletionWithDescriptions(
301 current_line, cursor, last_char, match_start_point, max_return_elements,
302 matches, descriptions);
303 }
304
HandleCompletion(const char * current_line,uint32_t cursor_pos,int match_start_point,int max_return_elements,lldb::SBStringList & matches)305 int SBCommandInterpreter::HandleCompletion(const char *current_line,
306 uint32_t cursor_pos,
307 int match_start_point,
308 int max_return_elements,
309 lldb::SBStringList &matches) {
310 LLDB_INSTRUMENT_VA(this, current_line, cursor_pos, match_start_point,
311 max_return_elements, matches);
312
313 const char *cursor = current_line + cursor_pos;
314 const char *last_char = current_line + strlen(current_line);
315 return HandleCompletion(current_line, cursor, last_char, match_start_point,
316 max_return_elements, matches);
317 }
318
HasCommands()319 bool SBCommandInterpreter::HasCommands() {
320 LLDB_INSTRUMENT_VA(this);
321
322 return (IsValid() ? m_opaque_ptr->HasCommands() : false);
323 }
324
HasAliases()325 bool SBCommandInterpreter::HasAliases() {
326 LLDB_INSTRUMENT_VA(this);
327
328 return (IsValid() ? m_opaque_ptr->HasAliases() : false);
329 }
330
HasAliasOptions()331 bool SBCommandInterpreter::HasAliasOptions() {
332 LLDB_INSTRUMENT_VA(this);
333
334 return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false);
335 }
336
IsInteractive()337 bool SBCommandInterpreter::IsInteractive() {
338 LLDB_INSTRUMENT_VA(this);
339
340 return (IsValid() ? m_opaque_ptr->IsInteractive() : false);
341 }
342
GetProcess()343 SBProcess SBCommandInterpreter::GetProcess() {
344 LLDB_INSTRUMENT_VA(this);
345
346 SBProcess sb_process;
347 ProcessSP process_sp;
348 if (IsValid()) {
349 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
350 if (target_sp) {
351 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
352 process_sp = target_sp->GetProcessSP();
353 sb_process.SetSP(process_sp);
354 }
355 }
356
357 return sb_process;
358 }
359
GetDebugger()360 SBDebugger SBCommandInterpreter::GetDebugger() {
361 LLDB_INSTRUMENT_VA(this);
362
363 SBDebugger sb_debugger;
364 if (IsValid())
365 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
366
367 return sb_debugger;
368 }
369
GetPromptOnQuit()370 bool SBCommandInterpreter::GetPromptOnQuit() {
371 LLDB_INSTRUMENT_VA(this);
372
373 return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false);
374 }
375
SetPromptOnQuit(bool b)376 void SBCommandInterpreter::SetPromptOnQuit(bool b) {
377 LLDB_INSTRUMENT_VA(this, b);
378
379 if (IsValid())
380 m_opaque_ptr->SetPromptOnQuit(b);
381 }
382
AllowExitCodeOnQuit(bool allow)383 void SBCommandInterpreter::AllowExitCodeOnQuit(bool allow) {
384 LLDB_INSTRUMENT_VA(this, allow);
385
386 if (m_opaque_ptr)
387 m_opaque_ptr->AllowExitCodeOnQuit(allow);
388 }
389
HasCustomQuitExitCode()390 bool SBCommandInterpreter::HasCustomQuitExitCode() {
391 LLDB_INSTRUMENT_VA(this);
392
393 bool exited = false;
394 if (m_opaque_ptr)
395 m_opaque_ptr->GetQuitExitCode(exited);
396 return exited;
397 }
398
GetQuitStatus()399 int SBCommandInterpreter::GetQuitStatus() {
400 LLDB_INSTRUMENT_VA(this);
401
402 bool exited = false;
403 return (m_opaque_ptr ? m_opaque_ptr->GetQuitExitCode(exited) : 0);
404 }
405
ResolveCommand(const char * command_line,SBCommandReturnObject & result)406 void SBCommandInterpreter::ResolveCommand(const char *command_line,
407 SBCommandReturnObject &result) {
408 LLDB_INSTRUMENT_VA(this, command_line, result);
409
410 result.Clear();
411 if (command_line && IsValid()) {
412 m_opaque_ptr->ResolveCommand(command_line, result.ref());
413 } else {
414 result->AppendError(
415 "SBCommandInterpreter or the command line is not valid");
416 }
417 }
418
get()419 CommandInterpreter *SBCommandInterpreter::get() { return m_opaque_ptr; }
420
ref()421 CommandInterpreter &SBCommandInterpreter::ref() {
422 assert(m_opaque_ptr);
423 return *m_opaque_ptr;
424 }
425
reset(lldb_private::CommandInterpreter * interpreter)426 void SBCommandInterpreter::reset(
427 lldb_private::CommandInterpreter *interpreter) {
428 m_opaque_ptr = interpreter;
429 }
430
SourceInitFileInGlobalDirectory(SBCommandReturnObject & result)431 void SBCommandInterpreter::SourceInitFileInGlobalDirectory(
432 SBCommandReturnObject &result) {
433 LLDB_INSTRUMENT_VA(this, result);
434
435 result.Clear();
436 if (IsValid()) {
437 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
438 std::unique_lock<std::recursive_mutex> lock;
439 if (target_sp)
440 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
441 m_opaque_ptr->SourceInitFileGlobal(result.ref());
442 } else {
443 result->AppendError("SBCommandInterpreter is not valid");
444 }
445 }
446
SourceInitFileInHomeDirectory(SBCommandReturnObject & result)447 void SBCommandInterpreter::SourceInitFileInHomeDirectory(
448 SBCommandReturnObject &result) {
449 LLDB_INSTRUMENT_VA(this, result);
450
451 SourceInitFileInHomeDirectory(result, /*is_repl=*/false);
452 }
453
SourceInitFileInHomeDirectory(SBCommandReturnObject & result,bool is_repl)454 void SBCommandInterpreter::SourceInitFileInHomeDirectory(
455 SBCommandReturnObject &result, bool is_repl) {
456 LLDB_INSTRUMENT_VA(this, result, is_repl);
457
458 result.Clear();
459 if (IsValid()) {
460 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
461 std::unique_lock<std::recursive_mutex> lock;
462 if (target_sp)
463 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
464 m_opaque_ptr->SourceInitFileHome(result.ref(), is_repl);
465 } else {
466 result->AppendError("SBCommandInterpreter is not valid");
467 }
468 }
469
SourceInitFileInCurrentWorkingDirectory(SBCommandReturnObject & result)470 void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory(
471 SBCommandReturnObject &result) {
472 LLDB_INSTRUMENT_VA(this, result);
473
474 result.Clear();
475 if (IsValid()) {
476 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
477 std::unique_lock<std::recursive_mutex> lock;
478 if (target_sp)
479 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
480 m_opaque_ptr->SourceInitFileCwd(result.ref());
481 } else {
482 result->AppendError("SBCommandInterpreter is not valid");
483 }
484 }
485
GetBroadcaster()486 SBBroadcaster SBCommandInterpreter::GetBroadcaster() {
487 LLDB_INSTRUMENT_VA(this);
488
489 SBBroadcaster broadcaster(m_opaque_ptr, false);
490
491 return broadcaster;
492 }
493
GetBroadcasterClass()494 const char *SBCommandInterpreter::GetBroadcasterClass() {
495 LLDB_INSTRUMENT();
496
497 return CommandInterpreter::GetStaticBroadcasterClass().AsCString();
498 }
499
GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type)500 const char *SBCommandInterpreter::GetArgumentTypeAsCString(
501 const lldb::CommandArgumentType arg_type) {
502 LLDB_INSTRUMENT_VA(arg_type);
503
504 return CommandObject::GetArgumentTypeAsCString(arg_type);
505 }
506
GetArgumentDescriptionAsCString(const lldb::CommandArgumentType arg_type)507 const char *SBCommandInterpreter::GetArgumentDescriptionAsCString(
508 const lldb::CommandArgumentType arg_type) {
509 LLDB_INSTRUMENT_VA(arg_type);
510
511 return CommandObject::GetArgumentDescriptionAsCString(arg_type);
512 }
513
EventIsCommandInterpreterEvent(const lldb::SBEvent & event)514 bool SBCommandInterpreter::EventIsCommandInterpreterEvent(
515 const lldb::SBEvent &event) {
516 LLDB_INSTRUMENT_VA(event);
517
518 return event.GetBroadcasterClass() ==
519 SBCommandInterpreter::GetBroadcasterClass();
520 }
521
SetCommandOverrideCallback(const char * command_name,lldb::CommandOverrideCallback callback,void * baton)522 bool SBCommandInterpreter::SetCommandOverrideCallback(
523 const char *command_name, lldb::CommandOverrideCallback callback,
524 void *baton) {
525 LLDB_INSTRUMENT_VA(this, command_name, callback, baton);
526
527 if (command_name && command_name[0] && IsValid()) {
528 llvm::StringRef command_name_str = command_name;
529 CommandObject *cmd_obj =
530 m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
531 if (cmd_obj) {
532 assert(command_name_str.empty());
533 cmd_obj->SetOverrideCallback(callback, baton);
534 return true;
535 }
536 }
537 return false;
538 }
539
AddMultiwordCommand(const char * name,const char * help)540 lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name,
541 const char *help) {
542 LLDB_INSTRUMENT_VA(this, name, help);
543
544 lldb::CommandObjectSP new_command_sp(
545 new CommandObjectMultiword(*m_opaque_ptr, name, help));
546 new_command_sp->GetAsMultiwordCommand()->SetRemovable(true);
547 Status add_error = m_opaque_ptr->AddUserCommand(name, new_command_sp, true);
548 if (add_error.Success())
549 return lldb::SBCommand(new_command_sp);
550 return lldb::SBCommand();
551 }
552
AddCommand(const char * name,lldb::SBCommandPluginInterface * impl,const char * help)553 lldb::SBCommand SBCommandInterpreter::AddCommand(
554 const char *name, lldb::SBCommandPluginInterface *impl, const char *help) {
555 LLDB_INSTRUMENT_VA(this, name, impl, help);
556
557 return AddCommand(name, impl, help, /*syntax=*/nullptr,
558 /*auto_repeat_command=*/"");
559 }
560
561 lldb::SBCommand
AddCommand(const char * name,lldb::SBCommandPluginInterface * impl,const char * help,const char * syntax)562 SBCommandInterpreter::AddCommand(const char *name,
563 lldb::SBCommandPluginInterface *impl,
564 const char *help, const char *syntax) {
565 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax);
566 return AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/"");
567 }
568
AddCommand(const char * name,lldb::SBCommandPluginInterface * impl,const char * help,const char * syntax,const char * auto_repeat_command)569 lldb::SBCommand SBCommandInterpreter::AddCommand(
570 const char *name, lldb::SBCommandPluginInterface *impl, const char *help,
571 const char *syntax, const char *auto_repeat_command) {
572 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax, auto_repeat_command);
573
574 lldb::CommandObjectSP new_command_sp;
575 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
576 *m_opaque_ptr, name, impl, help, syntax, /*flags=*/0,
577 auto_repeat_command);
578
579 Status add_error = m_opaque_ptr->AddUserCommand(name, new_command_sp, true);
580 if (add_error.Success())
581 return lldb::SBCommand(new_command_sp);
582 return lldb::SBCommand();
583 }
584
SBCommand()585 SBCommand::SBCommand() { LLDB_INSTRUMENT_VA(this); }
586
SBCommand(lldb::CommandObjectSP cmd_sp)587 SBCommand::SBCommand(lldb::CommandObjectSP cmd_sp) : m_opaque_sp(cmd_sp) {}
588
IsValid()589 bool SBCommand::IsValid() {
590 LLDB_INSTRUMENT_VA(this);
591 return this->operator bool();
592 }
operator bool() const593 SBCommand::operator bool() const {
594 LLDB_INSTRUMENT_VA(this);
595
596 return m_opaque_sp.get() != nullptr;
597 }
598
GetName()599 const char *SBCommand::GetName() {
600 LLDB_INSTRUMENT_VA(this);
601
602 return (IsValid() ? ConstString(m_opaque_sp->GetCommandName()).AsCString() : nullptr);
603 }
604
GetHelp()605 const char *SBCommand::GetHelp() {
606 LLDB_INSTRUMENT_VA(this);
607
608 return (IsValid() ? ConstString(m_opaque_sp->GetHelp()).AsCString()
609 : nullptr);
610 }
611
GetHelpLong()612 const char *SBCommand::GetHelpLong() {
613 LLDB_INSTRUMENT_VA(this);
614
615 return (IsValid() ? ConstString(m_opaque_sp->GetHelpLong()).AsCString()
616 : nullptr);
617 }
618
SetHelp(const char * help)619 void SBCommand::SetHelp(const char *help) {
620 LLDB_INSTRUMENT_VA(this, help);
621
622 if (IsValid())
623 m_opaque_sp->SetHelp(help);
624 }
625
SetHelpLong(const char * help)626 void SBCommand::SetHelpLong(const char *help) {
627 LLDB_INSTRUMENT_VA(this, help);
628
629 if (IsValid())
630 m_opaque_sp->SetHelpLong(help);
631 }
632
AddMultiwordCommand(const char * name,const char * help)633 lldb::SBCommand SBCommand::AddMultiwordCommand(const char *name,
634 const char *help) {
635 LLDB_INSTRUMENT_VA(this, name, help);
636
637 if (!IsValid())
638 return lldb::SBCommand();
639 if (!m_opaque_sp->IsMultiwordObject())
640 return lldb::SBCommand();
641 CommandObjectMultiword *new_command = new CommandObjectMultiword(
642 m_opaque_sp->GetCommandInterpreter(), name, help);
643 new_command->SetRemovable(true);
644 lldb::CommandObjectSP new_command_sp(new_command);
645 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
646 return lldb::SBCommand(new_command_sp);
647 return lldb::SBCommand();
648 }
649
AddCommand(const char * name,lldb::SBCommandPluginInterface * impl,const char * help)650 lldb::SBCommand SBCommand::AddCommand(const char *name,
651 lldb::SBCommandPluginInterface *impl,
652 const char *help) {
653 LLDB_INSTRUMENT_VA(this, name, impl, help);
654 return AddCommand(name, impl, help, /*syntax=*/nullptr,
655 /*auto_repeat_command=*/"");
656 }
657
AddCommand(const char * name,lldb::SBCommandPluginInterface * impl,const char * help,const char * syntax)658 lldb::SBCommand SBCommand::AddCommand(const char *name,
659 lldb::SBCommandPluginInterface *impl,
660 const char *help, const char *syntax) {
661 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax);
662 return AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/"");
663 }
664
AddCommand(const char * name,lldb::SBCommandPluginInterface * impl,const char * help,const char * syntax,const char * auto_repeat_command)665 lldb::SBCommand SBCommand::AddCommand(const char *name,
666 lldb::SBCommandPluginInterface *impl,
667 const char *help, const char *syntax,
668 const char *auto_repeat_command) {
669 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax, auto_repeat_command);
670
671 if (!IsValid())
672 return lldb::SBCommand();
673 if (!m_opaque_sp->IsMultiwordObject())
674 return lldb::SBCommand();
675 lldb::CommandObjectSP new_command_sp;
676 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
677 m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax,
678 /*flags=*/0, auto_repeat_command);
679 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
680 return lldb::SBCommand(new_command_sp);
681 return lldb::SBCommand();
682 }
683
GetFlags()684 uint32_t SBCommand::GetFlags() {
685 LLDB_INSTRUMENT_VA(this);
686
687 return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0);
688 }
689
SetFlags(uint32_t flags)690 void SBCommand::SetFlags(uint32_t flags) {
691 LLDB_INSTRUMENT_VA(this, flags);
692
693 if (IsValid())
694 m_opaque_sp->GetFlags().Set(flags);
695 }
696