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