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