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