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