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