1 //===-- SBCommandInterpreter.cpp --------------------------------*- C++ -*-===// 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/Listener.h" 16 17 #include "lldb/API/SBBroadcaster.h" 18 #include "lldb/API/SBCommandInterpreter.h" 19 #include "lldb/API/SBCommandReturnObject.h" 20 #include "lldb/API/SBEvent.h" 21 #include "lldb/API/SBExecutionContext.h" 22 #include "lldb/API/SBListener.h" 23 #include "lldb/API/SBProcess.h" 24 #include "lldb/API/SBStream.h" 25 #include "lldb/API/SBStringList.h" 26 #include "lldb/API/SBTarget.h" 27 28 #include <memory> 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() { 34 m_opaque_up.reset(new CommandInterpreterRunOptions()); 35 } 36 37 SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default; 38 39 bool SBCommandInterpreterRunOptions::GetStopOnContinue() const { 40 return m_opaque_up->GetStopOnContinue(); 41 } 42 43 void SBCommandInterpreterRunOptions::SetStopOnContinue(bool stop_on_continue) { 44 m_opaque_up->SetStopOnContinue(stop_on_continue); 45 } 46 47 bool SBCommandInterpreterRunOptions::GetStopOnError() const { 48 return m_opaque_up->GetStopOnError(); 49 } 50 51 void SBCommandInterpreterRunOptions::SetStopOnError(bool stop_on_error) { 52 m_opaque_up->SetStopOnError(stop_on_error); 53 } 54 55 bool SBCommandInterpreterRunOptions::GetStopOnCrash() const { 56 return m_opaque_up->GetStopOnCrash(); 57 } 58 59 void SBCommandInterpreterRunOptions::SetStopOnCrash(bool stop_on_crash) { 60 m_opaque_up->SetStopOnCrash(stop_on_crash); 61 } 62 63 bool SBCommandInterpreterRunOptions::GetEchoCommands() const { 64 return m_opaque_up->GetEchoCommands(); 65 } 66 67 void SBCommandInterpreterRunOptions::SetEchoCommands(bool echo_commands) { 68 m_opaque_up->SetEchoCommands(echo_commands); 69 } 70 71 bool SBCommandInterpreterRunOptions::GetEchoCommentCommands() const { 72 return m_opaque_up->GetEchoCommentCommands(); 73 } 74 75 void SBCommandInterpreterRunOptions::SetEchoCommentCommands(bool echo) { 76 m_opaque_up->SetEchoCommentCommands(echo); 77 } 78 79 bool SBCommandInterpreterRunOptions::GetPrintResults() const { 80 return m_opaque_up->GetPrintResults(); 81 } 82 83 void SBCommandInterpreterRunOptions::SetPrintResults(bool print_results) { 84 m_opaque_up->SetPrintResults(print_results); 85 } 86 87 bool SBCommandInterpreterRunOptions::GetAddToHistory() const { 88 return m_opaque_up->GetAddToHistory(); 89 } 90 91 void SBCommandInterpreterRunOptions::SetAddToHistory(bool add_to_history) { 92 m_opaque_up->SetAddToHistory(add_to_history); 93 } 94 95 lldb_private::CommandInterpreterRunOptions * 96 SBCommandInterpreterRunOptions::get() const { 97 return m_opaque_up.get(); 98 } 99 100 lldb_private::CommandInterpreterRunOptions & 101 SBCommandInterpreterRunOptions::ref() const { 102 return *m_opaque_up; 103 } 104 105 class CommandPluginInterfaceImplementation : public CommandObjectParsed { 106 public: 107 CommandPluginInterfaceImplementation(CommandInterpreter &interpreter, 108 const char *name, 109 lldb::SBCommandPluginInterface *backend, 110 const char *help = nullptr, 111 const char *syntax = nullptr, 112 uint32_t flags = 0) 113 : CommandObjectParsed(interpreter, name, help, syntax, flags), 114 m_backend(backend) {} 115 116 bool IsRemovable() const override { return true; } 117 118 protected: 119 bool DoExecute(Args &command, CommandReturnObject &result) override { 120 SBCommandReturnObject sb_return(&result); 121 SBCommandInterpreter sb_interpreter(&m_interpreter); 122 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); 123 bool ret = m_backend->DoExecute( 124 debugger_sb, (char **)command.GetArgumentVector(), sb_return); 125 sb_return.Release(); 126 return ret; 127 } 128 std::shared_ptr<lldb::SBCommandPluginInterface> m_backend; 129 }; 130 131 SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter) 132 : m_opaque_ptr(interpreter) { 133 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 134 135 if (log) 136 log->Printf("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" 137 " => SBCommandInterpreter(%p)", 138 static_cast<void *>(interpreter), 139 static_cast<void *>(m_opaque_ptr)); 140 } 141 142 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) 143 : m_opaque_ptr(rhs.m_opaque_ptr) {} 144 145 SBCommandInterpreter::~SBCommandInterpreter() = default; 146 147 const SBCommandInterpreter &SBCommandInterpreter:: 148 operator=(const SBCommandInterpreter &rhs) { 149 m_opaque_ptr = rhs.m_opaque_ptr; 150 return *this; 151 } 152 153 bool SBCommandInterpreter::IsValid() const { return m_opaque_ptr != nullptr; } 154 155 bool SBCommandInterpreter::CommandExists(const char *cmd) { 156 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd) 157 : false); 158 } 159 160 bool SBCommandInterpreter::AliasExists(const char *cmd) { 161 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd) 162 : false); 163 } 164 165 bool SBCommandInterpreter::IsActive() { 166 return (IsValid() ? m_opaque_ptr->IsActive() : false); 167 } 168 169 bool SBCommandInterpreter::WasInterrupted() const { 170 return (IsValid() ? m_opaque_ptr->WasInterrupted() : false); 171 } 172 173 const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) { 174 return (IsValid() 175 ? m_opaque_ptr->GetDebugger() 176 .GetTopIOHandlerControlSequence(ch) 177 .GetCString() 178 : nullptr); 179 } 180 181 lldb::ReturnStatus 182 SBCommandInterpreter::HandleCommand(const char *command_line, 183 SBCommandReturnObject &result, 184 bool add_to_history) { 185 SBExecutionContext sb_exe_ctx; 186 return HandleCommand(command_line, sb_exe_ctx, result, add_to_history); 187 } 188 189 lldb::ReturnStatus SBCommandInterpreter::HandleCommand( 190 const char *command_line, SBExecutionContext &override_context, 191 SBCommandReturnObject &result, bool add_to_history) { 192 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 193 194 if (log) 195 log->Printf("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", " 196 "SBCommandReturnObject(%p), add_to_history=%i)", 197 static_cast<void *>(m_opaque_ptr), command_line, 198 static_cast<void *>(result.get()), add_to_history); 199 200 ExecutionContext ctx, *ctx_ptr; 201 if (override_context.get()) { 202 ctx = override_context.get()->Lock(true); 203 ctx_ptr = &ctx; 204 } else 205 ctx_ptr = nullptr; 206 207 result.Clear(); 208 if (command_line && IsValid()) { 209 result.ref().SetInteractive(false); 210 m_opaque_ptr->HandleCommand(command_line, 211 add_to_history ? eLazyBoolYes : eLazyBoolNo, 212 result.ref(), ctx_ptr); 213 } else { 214 result->AppendError( 215 "SBCommandInterpreter or the command line is not valid"); 216 result->SetStatus(eReturnStatusFailed); 217 } 218 219 // We need to get the value again, in case the command disabled the log! 220 log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); 221 if (log) { 222 SBStream sstr; 223 result.GetDescription(sstr); 224 log->Printf("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", " 225 "SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", 226 static_cast<void *>(m_opaque_ptr), command_line, 227 static_cast<void *>(result.get()), sstr.GetData(), 228 add_to_history, result.GetStatus()); 229 } 230 231 return result.GetStatus(); 232 } 233 234 void SBCommandInterpreter::HandleCommandsFromFile( 235 lldb::SBFileSpec &file, lldb::SBExecutionContext &override_context, 236 lldb::SBCommandInterpreterRunOptions &options, 237 lldb::SBCommandReturnObject result) { 238 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 239 240 if (log) { 241 SBStream s; 242 file.GetDescription(s); 243 log->Printf("SBCommandInterpreter(%p)::HandleCommandsFromFile " 244 "(file=\"%s\", SBCommandReturnObject(%p))", 245 static_cast<void *>(m_opaque_ptr), s.GetData(), 246 static_cast<void *>(result.get())); 247 } 248 249 if (!IsValid()) { 250 result->AppendError("SBCommandInterpreter is not valid."); 251 result->SetStatus(eReturnStatusFailed); 252 return; 253 } 254 255 if (!file.IsValid()) { 256 SBStream s; 257 file.GetDescription(s); 258 result->AppendErrorWithFormat("File is not valid: %s.", s.GetData()); 259 result->SetStatus(eReturnStatusFailed); 260 } 261 262 FileSpec tmp_spec = file.ref(); 263 ExecutionContext ctx, *ctx_ptr; 264 if (override_context.get()) { 265 ctx = override_context.get()->Lock(true); 266 ctx_ptr = &ctx; 267 } else 268 ctx_ptr = nullptr; 269 270 m_opaque_ptr->HandleCommandsFromFile(tmp_spec, ctx_ptr, options.ref(), 271 result.ref()); 272 } 273 274 int SBCommandInterpreter::HandleCompletion( 275 const char *current_line, const char *cursor, const char *last_char, 276 int match_start_point, int max_return_elements, SBStringList &matches) { 277 SBStringList dummy_descriptions; 278 return HandleCompletionWithDescriptions( 279 current_line, cursor, last_char, match_start_point, max_return_elements, 280 matches, dummy_descriptions); 281 } 282 283 int SBCommandInterpreter::HandleCompletionWithDescriptions( 284 const char *current_line, const char *cursor, const char *last_char, 285 int match_start_point, int max_return_elements, SBStringList &matches, 286 SBStringList &descriptions) { 287 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 288 int num_completions = 0; 289 290 // Sanity check the arguments that are passed in: cursor & last_char have to 291 // be within the current_line. 292 if (current_line == nullptr || cursor == nullptr || last_char == nullptr) 293 return 0; 294 295 if (cursor < current_line || last_char < current_line) 296 return 0; 297 298 size_t current_line_size = strlen(current_line); 299 if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) || 300 last_char - current_line > static_cast<ptrdiff_t>(current_line_size)) 301 return 0; 302 303 if (log) 304 log->Printf("SBCommandInterpreter(%p)::HandleCompletion " 305 "(current_line=\"%s\", cursor at: %" PRId64 306 ", last char at: %" PRId64 307 ", match_start_point: %d, max_return_elements: %d)", 308 static_cast<void *>(m_opaque_ptr), current_line, 309 static_cast<uint64_t>(cursor - current_line), 310 static_cast<uint64_t>(last_char - current_line), 311 match_start_point, max_return_elements); 312 313 if (IsValid()) { 314 lldb_private::StringList lldb_matches, lldb_descriptions; 315 num_completions = m_opaque_ptr->HandleCompletion( 316 current_line, cursor, last_char, match_start_point, max_return_elements, 317 lldb_matches, lldb_descriptions); 318 319 SBStringList temp_matches_list(&lldb_matches); 320 matches.AppendList(temp_matches_list); 321 SBStringList temp_descriptions_list(&lldb_descriptions); 322 descriptions.AppendList(temp_descriptions_list); 323 } 324 if (log) 325 log->Printf( 326 "SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", 327 static_cast<void *>(m_opaque_ptr), num_completions); 328 329 return num_completions; 330 } 331 332 int SBCommandInterpreter::HandleCompletionWithDescriptions( 333 const char *current_line, uint32_t cursor_pos, int match_start_point, 334 int max_return_elements, SBStringList &matches, 335 SBStringList &descriptions) { 336 const char *cursor = current_line + cursor_pos; 337 const char *last_char = current_line + strlen(current_line); 338 return HandleCompletionWithDescriptions( 339 current_line, cursor, last_char, match_start_point, max_return_elements, 340 matches, descriptions); 341 } 342 343 int SBCommandInterpreter::HandleCompletion(const char *current_line, 344 uint32_t cursor_pos, 345 int match_start_point, 346 int max_return_elements, 347 lldb::SBStringList &matches) { 348 const char *cursor = current_line + cursor_pos; 349 const char *last_char = current_line + strlen(current_line); 350 return HandleCompletion(current_line, cursor, last_char, match_start_point, 351 max_return_elements, matches); 352 } 353 354 bool SBCommandInterpreter::HasCommands() { 355 return (IsValid() ? m_opaque_ptr->HasCommands() : false); 356 } 357 358 bool SBCommandInterpreter::HasAliases() { 359 return (IsValid() ? m_opaque_ptr->HasAliases() : false); 360 } 361 362 bool SBCommandInterpreter::HasAliasOptions() { 363 return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false); 364 } 365 366 SBProcess SBCommandInterpreter::GetProcess() { 367 SBProcess sb_process; 368 ProcessSP process_sp; 369 if (IsValid()) { 370 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 371 if (target_sp) { 372 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); 373 process_sp = target_sp->GetProcessSP(); 374 sb_process.SetSP(process_sp); 375 } 376 } 377 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 378 379 if (log) 380 log->Printf("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", 381 static_cast<void *>(m_opaque_ptr), 382 static_cast<void *>(process_sp.get())); 383 384 return sb_process; 385 } 386 387 SBDebugger SBCommandInterpreter::GetDebugger() { 388 SBDebugger sb_debugger; 389 if (IsValid()) 390 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this()); 391 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 392 393 if (log) 394 log->Printf("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)", 395 static_cast<void *>(m_opaque_ptr), 396 static_cast<void *>(sb_debugger.get())); 397 398 return sb_debugger; 399 } 400 401 bool SBCommandInterpreter::GetPromptOnQuit() { 402 return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false); 403 } 404 405 void SBCommandInterpreter::SetPromptOnQuit(bool b) { 406 if (IsValid()) 407 m_opaque_ptr->SetPromptOnQuit(b); 408 } 409 410 void SBCommandInterpreter::AllowExitCodeOnQuit(bool allow) { 411 if (m_opaque_ptr) 412 m_opaque_ptr->AllowExitCodeOnQuit(allow); 413 } 414 415 bool SBCommandInterpreter::HasCustomQuitExitCode() { 416 bool exited = false; 417 if (m_opaque_ptr) 418 m_opaque_ptr->GetQuitExitCode(exited); 419 return exited; 420 } 421 422 int SBCommandInterpreter::GetQuitStatus() { 423 bool exited = false; 424 return (m_opaque_ptr ? m_opaque_ptr->GetQuitExitCode(exited) : 0); 425 } 426 427 void SBCommandInterpreter::ResolveCommand(const char *command_line, 428 SBCommandReturnObject &result) { 429 result.Clear(); 430 if (command_line && IsValid()) { 431 m_opaque_ptr->ResolveCommand(command_line, result.ref()); 432 } else { 433 result->AppendError( 434 "SBCommandInterpreter or the command line is not valid"); 435 result->SetStatus(eReturnStatusFailed); 436 } 437 } 438 439 CommandInterpreter *SBCommandInterpreter::get() { return m_opaque_ptr; } 440 441 CommandInterpreter &SBCommandInterpreter::ref() { 442 assert(m_opaque_ptr); 443 return *m_opaque_ptr; 444 } 445 446 void SBCommandInterpreter::reset( 447 lldb_private::CommandInterpreter *interpreter) { 448 m_opaque_ptr = interpreter; 449 } 450 451 void SBCommandInterpreter::SourceInitFileInHomeDirectory( 452 SBCommandReturnObject &result) { 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->SourceInitFile(false, result.ref()); 460 } else { 461 result->AppendError("SBCommandInterpreter is not valid"); 462 result->SetStatus(eReturnStatusFailed); 463 } 464 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 465 466 if (log) 467 log->Printf("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory " 468 "(&SBCommandReturnObject(%p))", 469 static_cast<void *>(m_opaque_ptr), 470 static_cast<void *>(result.get())); 471 } 472 473 void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory( 474 SBCommandReturnObject &result) { 475 result.Clear(); 476 if (IsValid()) { 477 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 478 std::unique_lock<std::recursive_mutex> lock; 479 if (target_sp) 480 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 481 m_opaque_ptr->SourceInitFile(true, result.ref()); 482 } else { 483 result->AppendError("SBCommandInterpreter is not valid"); 484 result->SetStatus(eReturnStatusFailed); 485 } 486 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 487 488 if (log) 489 log->Printf( 490 "SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory " 491 "(&SBCommandReturnObject(%p))", 492 static_cast<void *>(m_opaque_ptr), static_cast<void *>(result.get())); 493 } 494 495 SBBroadcaster SBCommandInterpreter::GetBroadcaster() { 496 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 497 498 SBBroadcaster broadcaster(m_opaque_ptr, false); 499 500 if (log) 501 log->Printf( 502 "SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", 503 static_cast<void *>(m_opaque_ptr), 504 static_cast<void *>(broadcaster.get())); 505 506 return broadcaster; 507 } 508 509 const char *SBCommandInterpreter::GetBroadcasterClass() { 510 return CommandInterpreter::GetStaticBroadcasterClass().AsCString(); 511 } 512 513 const char *SBCommandInterpreter::GetArgumentTypeAsCString( 514 const lldb::CommandArgumentType arg_type) { 515 return CommandObject::GetArgumentTypeAsCString(arg_type); 516 } 517 518 const char *SBCommandInterpreter::GetArgumentDescriptionAsCString( 519 const lldb::CommandArgumentType arg_type) { 520 return CommandObject::GetArgumentDescriptionAsCString(arg_type); 521 } 522 523 bool SBCommandInterpreter::EventIsCommandInterpreterEvent( 524 const lldb::SBEvent &event) { 525 return event.GetBroadcasterClass() == 526 SBCommandInterpreter::GetBroadcasterClass(); 527 } 528 529 bool SBCommandInterpreter::SetCommandOverrideCallback( 530 const char *command_name, lldb::CommandOverrideCallback callback, 531 void *baton) { 532 if (command_name && command_name[0] && IsValid()) { 533 llvm::StringRef command_name_str = command_name; 534 CommandObject *cmd_obj = 535 m_opaque_ptr->GetCommandObjectForCommand(command_name_str); 536 if (cmd_obj) { 537 assert(command_name_str.empty()); 538 cmd_obj->SetOverrideCallback(callback, baton); 539 return true; 540 } 541 } 542 return false; 543 } 544 545 lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name, 546 const char *help) { 547 CommandObjectMultiword *new_command = 548 new CommandObjectMultiword(*m_opaque_ptr, name, help); 549 new_command->SetRemovable(true); 550 lldb::CommandObjectSP new_command_sp(new_command); 551 if (new_command_sp && 552 m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 553 return lldb::SBCommand(new_command_sp); 554 return lldb::SBCommand(); 555 } 556 557 lldb::SBCommand SBCommandInterpreter::AddCommand( 558 const char *name, lldb::SBCommandPluginInterface *impl, const char *help) { 559 lldb::CommandObjectSP new_command_sp; 560 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>( 561 *m_opaque_ptr, name, impl, help); 562 563 if (new_command_sp && 564 m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 565 return lldb::SBCommand(new_command_sp); 566 return lldb::SBCommand(); 567 } 568 569 lldb::SBCommand 570 SBCommandInterpreter::AddCommand(const char *name, 571 lldb::SBCommandPluginInterface *impl, 572 const char *help, const char *syntax) { 573 lldb::CommandObjectSP new_command_sp; 574 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>( 575 *m_opaque_ptr, name, impl, help, syntax); 576 577 if (new_command_sp && 578 m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 579 return lldb::SBCommand(new_command_sp); 580 return lldb::SBCommand(); 581 } 582 583 SBCommand::SBCommand() = default; 584 585 SBCommand::SBCommand(lldb::CommandObjectSP cmd_sp) : m_opaque_sp(cmd_sp) {} 586 587 bool SBCommand::IsValid() { return m_opaque_sp.get() != nullptr; } 588 589 const char *SBCommand::GetName() { 590 return (IsValid() ? ConstString(m_opaque_sp->GetCommandName()).AsCString() : nullptr); 591 } 592 593 const char *SBCommand::GetHelp() { 594 return (IsValid() ? ConstString(m_opaque_sp->GetHelp()).AsCString() 595 : nullptr); 596 } 597 598 const char *SBCommand::GetHelpLong() { 599 return (IsValid() ? ConstString(m_opaque_sp->GetHelpLong()).AsCString() 600 : nullptr); 601 } 602 603 void SBCommand::SetHelp(const char *help) { 604 if (IsValid()) 605 m_opaque_sp->SetHelp(help); 606 } 607 608 void SBCommand::SetHelpLong(const char *help) { 609 if (IsValid()) 610 m_opaque_sp->SetHelpLong(help); 611 } 612 613 lldb::SBCommand SBCommand::AddMultiwordCommand(const char *name, 614 const char *help) { 615 if (!IsValid()) 616 return lldb::SBCommand(); 617 if (!m_opaque_sp->IsMultiwordObject()) 618 return lldb::SBCommand(); 619 CommandObjectMultiword *new_command = new CommandObjectMultiword( 620 m_opaque_sp->GetCommandInterpreter(), name, help); 621 new_command->SetRemovable(true); 622 lldb::CommandObjectSP new_command_sp(new_command); 623 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) 624 return lldb::SBCommand(new_command_sp); 625 return lldb::SBCommand(); 626 } 627 628 lldb::SBCommand SBCommand::AddCommand(const char *name, 629 lldb::SBCommandPluginInterface *impl, 630 const char *help) { 631 if (!IsValid()) 632 return lldb::SBCommand(); 633 if (!m_opaque_sp->IsMultiwordObject()) 634 return lldb::SBCommand(); 635 lldb::CommandObjectSP new_command_sp; 636 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>( 637 m_opaque_sp->GetCommandInterpreter(), name, impl, help); 638 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) 639 return lldb::SBCommand(new_command_sp); 640 return lldb::SBCommand(); 641 } 642 643 lldb::SBCommand SBCommand::AddCommand(const char *name, 644 lldb::SBCommandPluginInterface *impl, 645 const char *help, const char *syntax) { 646 if (!IsValid()) 647 return lldb::SBCommand(); 648 if (!m_opaque_sp->IsMultiwordObject()) 649 return lldb::SBCommand(); 650 lldb::CommandObjectSP new_command_sp; 651 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>( 652 m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax); 653 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) 654 return lldb::SBCommand(new_command_sp); 655 return lldb::SBCommand(); 656 } 657 658 uint32_t SBCommand::GetFlags() { 659 return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0); 660 } 661 662 void SBCommand::SetFlags(uint32_t flags) { 663 if (IsValid()) 664 m_opaque_sp->GetFlags().Set(flags); 665 } 666