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