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