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