1 //===-- CommandObject.cpp -------------------------------------------------===// 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/Interpreter/CommandObject.h" 10 11 #include <map> 12 #include <sstream> 13 #include <string> 14 15 #include <cctype> 16 #include <cstdlib> 17 18 #include "lldb/Core/Address.h" 19 #include "lldb/Interpreter/CommandOptionArgumentTable.h" 20 #include "lldb/Interpreter/Options.h" 21 #include "lldb/Utility/ArchSpec.h" 22 #include "llvm/ADT/ScopeExit.h" 23 24 // These are for the Sourcename completers. 25 // FIXME: Make a separate file for the completers. 26 #include "lldb/DataFormatters/FormatManager.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/Target.h" 29 #include "lldb/Utility/FileSpec.h" 30 #include "lldb/Utility/FileSpecList.h" 31 32 #include "lldb/Target/Language.h" 33 34 #include "lldb/Interpreter/CommandInterpreter.h" 35 #include "lldb/Interpreter/CommandOptionArgumentTable.h" 36 #include "lldb/Interpreter/CommandReturnObject.h" 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 // CommandObject 42 43 CommandObject::CommandObject(CommandInterpreter &interpreter, 44 llvm::StringRef name, llvm::StringRef help, 45 llvm::StringRef syntax, uint32_t flags) 46 : m_interpreter(interpreter), m_cmd_name(std::string(name)), 47 m_flags(flags), m_deprecated_command_override_callback(nullptr), 48 m_command_override_callback(nullptr), m_command_override_baton(nullptr) { 49 m_cmd_help_short = std::string(help); 50 m_cmd_syntax = std::string(syntax); 51 } 52 53 Debugger &CommandObject::GetDebugger() { return m_interpreter.GetDebugger(); } 54 55 llvm::StringRef CommandObject::GetHelp() { return m_cmd_help_short; } 56 57 llvm::StringRef CommandObject::GetHelpLong() { return m_cmd_help_long; } 58 59 llvm::StringRef CommandObject::GetSyntax() { 60 if (!m_cmd_syntax.empty()) 61 return m_cmd_syntax; 62 63 StreamString syntax_str; 64 syntax_str.PutCString(GetCommandName()); 65 66 if (!IsDashDashCommand() && GetOptions() != nullptr) 67 syntax_str.PutCString(" <cmd-options>"); 68 69 if (!m_arguments.empty()) { 70 syntax_str.PutCString(" "); 71 72 if (!IsDashDashCommand() && WantsRawCommandString() && GetOptions() && 73 GetOptions()->NumCommandOptions()) 74 syntax_str.PutCString("-- "); 75 GetFormattedCommandArguments(syntax_str); 76 } 77 m_cmd_syntax = std::string(syntax_str.GetString()); 78 79 return m_cmd_syntax; 80 } 81 82 llvm::StringRef CommandObject::GetCommandName() const { return m_cmd_name; } 83 84 void CommandObject::SetCommandName(llvm::StringRef name) { 85 m_cmd_name = std::string(name); 86 } 87 88 void CommandObject::SetHelp(llvm::StringRef str) { 89 m_cmd_help_short = std::string(str); 90 } 91 92 void CommandObject::SetHelpLong(llvm::StringRef str) { 93 m_cmd_help_long = std::string(str); 94 } 95 96 void CommandObject::SetSyntax(llvm::StringRef str) { 97 m_cmd_syntax = std::string(str); 98 } 99 100 Options *CommandObject::GetOptions() { 101 // By default commands don't have options unless this virtual function is 102 // overridden by base classes. 103 return nullptr; 104 } 105 106 bool CommandObject::ParseOptions(Args &args, CommandReturnObject &result) { 107 // See if the subclass has options? 108 Options *options = GetOptions(); 109 if (options != nullptr) { 110 Status error; 111 112 auto exe_ctx = GetCommandInterpreter().GetExecutionContext(); 113 options->NotifyOptionParsingStarting(&exe_ctx); 114 115 const bool require_validation = true; 116 llvm::Expected<Args> args_or = options->Parse( 117 args, &exe_ctx, GetCommandInterpreter().GetPlatform(true), 118 require_validation); 119 120 if (args_or) { 121 args = std::move(*args_or); 122 error = options->NotifyOptionParsingFinished(&exe_ctx); 123 } else 124 error = Status::FromError(args_or.takeError()); 125 126 if (error.Success()) { 127 if (options->VerifyOptions(result)) 128 return true; 129 } else { 130 result.SetError(error.takeError()); 131 } 132 result.SetStatus(eReturnStatusFailed); 133 return false; 134 } 135 return true; 136 } 137 138 bool CommandObject::CheckRequirements(CommandReturnObject &result) { 139 // Nothing should be stored in m_exe_ctx between running commands as 140 // m_exe_ctx has shared pointers to the target, process, thread and frame and 141 // we don't want any CommandObject instances to keep any of these objects 142 // around longer than for a single command. Every command should call 143 // CommandObject::Cleanup() after it has completed. 144 assert(!m_exe_ctx.GetTargetPtr()); 145 assert(!m_exe_ctx.GetProcessPtr()); 146 assert(!m_exe_ctx.GetThreadPtr()); 147 assert(!m_exe_ctx.GetFramePtr()); 148 149 // Lock down the interpreter's execution context prior to running the command 150 // so we guarantee the selected target, process, thread and frame can't go 151 // away during the execution 152 m_exe_ctx = m_interpreter.GetExecutionContext(); 153 154 const uint32_t flags = GetFlags().Get(); 155 if (flags & (eCommandRequiresTarget | eCommandRequiresProcess | 156 eCommandRequiresThread | eCommandRequiresFrame | 157 eCommandTryTargetAPILock)) { 158 159 if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope()) { 160 result.AppendError(GetInvalidTargetDescription()); 161 return false; 162 } 163 164 if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope()) { 165 if (!m_exe_ctx.HasTargetScope()) 166 result.AppendError(GetInvalidTargetDescription()); 167 else 168 result.AppendError(GetInvalidProcessDescription()); 169 return false; 170 } 171 172 if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope()) { 173 if (!m_exe_ctx.HasTargetScope()) 174 result.AppendError(GetInvalidTargetDescription()); 175 else if (!m_exe_ctx.HasProcessScope()) 176 result.AppendError(GetInvalidProcessDescription()); 177 else 178 result.AppendError(GetInvalidThreadDescription()); 179 return false; 180 } 181 182 if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope()) { 183 if (!m_exe_ctx.HasTargetScope()) 184 result.AppendError(GetInvalidTargetDescription()); 185 else if (!m_exe_ctx.HasProcessScope()) 186 result.AppendError(GetInvalidProcessDescription()); 187 else if (!m_exe_ctx.HasThreadScope()) 188 result.AppendError(GetInvalidThreadDescription()); 189 else 190 result.AppendError(GetInvalidFrameDescription()); 191 return false; 192 } 193 194 if ((flags & eCommandRequiresRegContext) && 195 (m_exe_ctx.GetRegisterContext() == nullptr)) { 196 result.AppendError(GetInvalidRegContextDescription()); 197 return false; 198 } 199 200 if (flags & eCommandTryTargetAPILock) { 201 Target *target = m_exe_ctx.GetTargetPtr(); 202 if (target) 203 m_api_locker = 204 std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); 205 } 206 } 207 208 if (GetFlags().AnySet(eCommandProcessMustBeLaunched | 209 eCommandProcessMustBePaused)) { 210 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 211 if (process == nullptr) { 212 // A process that is not running is considered paused. 213 if (GetFlags().Test(eCommandProcessMustBeLaunched)) { 214 result.AppendError("Process must exist."); 215 return false; 216 } 217 } else { 218 StateType state = process->GetState(); 219 switch (state) { 220 case eStateInvalid: 221 case eStateSuspended: 222 case eStateCrashed: 223 case eStateStopped: 224 break; 225 226 case eStateConnected: 227 case eStateAttaching: 228 case eStateLaunching: 229 case eStateDetached: 230 case eStateExited: 231 case eStateUnloaded: 232 if (GetFlags().Test(eCommandProcessMustBeLaunched)) { 233 result.AppendError("Process must be launched."); 234 return false; 235 } 236 break; 237 238 case eStateRunning: 239 case eStateStepping: 240 if (GetFlags().Test(eCommandProcessMustBePaused)) { 241 result.AppendError("Process is running. Use 'process interrupt' to " 242 "pause execution."); 243 return false; 244 } 245 } 246 } 247 } 248 249 if (GetFlags().Test(eCommandProcessMustBeTraced)) { 250 Target *target = m_exe_ctx.GetTargetPtr(); 251 if (target && !target->GetTrace()) { 252 result.AppendError("Process is not being traced."); 253 return false; 254 } 255 } 256 257 return true; 258 } 259 260 void CommandObject::Cleanup() { 261 m_exe_ctx.Clear(); 262 if (m_api_locker.owns_lock()) 263 m_api_locker.unlock(); 264 } 265 266 void CommandObject::HandleCompletion(CompletionRequest &request) { 267 268 m_exe_ctx = m_interpreter.GetExecutionContext(); 269 auto reset_ctx = llvm::make_scope_exit([this]() { Cleanup(); }); 270 271 // Default implementation of WantsCompletion() is !WantsRawCommandString(). 272 // Subclasses who want raw command string but desire, for example, argument 273 // completion should override WantsCompletion() to return true, instead. 274 if (WantsRawCommandString() && !WantsCompletion()) { 275 // FIXME: Abstract telling the completion to insert the completion 276 // character. 277 return; 278 } else { 279 // Can we do anything generic with the options? 280 Options *cur_options = GetOptions(); 281 CommandReturnObject result(m_interpreter.GetDebugger().GetUseColor()); 282 OptionElementVector opt_element_vector; 283 284 if (cur_options != nullptr) { 285 opt_element_vector = cur_options->ParseForCompletion( 286 request.GetParsedLine(), request.GetCursorIndex()); 287 288 bool handled_by_options = cur_options->HandleOptionCompletion( 289 request, opt_element_vector, GetCommandInterpreter()); 290 if (handled_by_options) 291 return; 292 } 293 294 // If we got here, the last word is not an option or an option argument. 295 HandleArgumentCompletion(request, opt_element_vector); 296 } 297 } 298 299 void CommandObject::HandleArgumentCompletion( 300 CompletionRequest &request, OptionElementVector &opt_element_vector) { 301 size_t num_arg_entries = GetNumArgumentEntries(); 302 if (num_arg_entries != 1) 303 return; 304 305 CommandArgumentEntry *entry_ptr = GetArgumentEntryAtIndex(0); 306 if (!entry_ptr) { 307 assert(entry_ptr && "We said there was one entry, but there wasn't."); 308 return; // Not worth crashing if asserts are off... 309 } 310 311 CommandArgumentEntry &entry = *entry_ptr; 312 // For now, we only handle the simple case of one homogenous argument type. 313 if (entry.size() != 1) 314 return; 315 316 // Look up the completion type, and if it has one, invoke it: 317 const CommandObject::ArgumentTableEntry *arg_entry = 318 FindArgumentDataByType(entry[0].arg_type); 319 const ArgumentRepetitionType repeat = entry[0].arg_repetition; 320 321 if (arg_entry == nullptr || arg_entry->completion_type == lldb::eNoCompletion) 322 return; 323 324 // FIXME: This should be handled higher in the Command Parser. 325 // Check the case where this command only takes one argument, and don't do 326 // the completion if we aren't on the first entry: 327 if (repeat == eArgRepeatPlain && request.GetCursorIndex() != 0) 328 return; 329 330 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 331 GetCommandInterpreter(), arg_entry->completion_type, request, nullptr); 332 333 } 334 335 336 bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word, 337 bool search_short_help, 338 bool search_long_help, 339 bool search_syntax, 340 bool search_options) { 341 std::string options_usage_help; 342 343 bool found_word = false; 344 345 llvm::StringRef short_help = GetHelp(); 346 llvm::StringRef long_help = GetHelpLong(); 347 llvm::StringRef syntax_help = GetSyntax(); 348 349 if (search_short_help && short_help.contains_insensitive(search_word)) 350 found_word = true; 351 else if (search_long_help && long_help.contains_insensitive(search_word)) 352 found_word = true; 353 else if (search_syntax && syntax_help.contains_insensitive(search_word)) 354 found_word = true; 355 356 if (!found_word && search_options && GetOptions() != nullptr) { 357 StreamString usage_help; 358 GetOptions()->GenerateOptionUsage( 359 usage_help, *this, 360 GetCommandInterpreter().GetDebugger().GetTerminalWidth()); 361 if (!usage_help.Empty()) { 362 llvm::StringRef usage_text = usage_help.GetString(); 363 if (usage_text.contains_insensitive(search_word)) 364 found_word = true; 365 } 366 } 367 368 return found_word; 369 } 370 371 bool CommandObject::ParseOptionsAndNotify(Args &args, 372 CommandReturnObject &result, 373 OptionGroupOptions &group_options, 374 ExecutionContext &exe_ctx) { 375 if (!ParseOptions(args, result)) 376 return false; 377 378 Status error(group_options.NotifyOptionParsingFinished(&exe_ctx)); 379 if (error.Fail()) { 380 result.AppendError(error.AsCString()); 381 return false; 382 } 383 return true; 384 } 385 386 void CommandObject::AddSimpleArgumentList( 387 CommandArgumentType arg_type, ArgumentRepetitionType repetition_type) { 388 389 CommandArgumentEntry arg_entry; 390 CommandArgumentData simple_arg; 391 392 // Define the first (and only) variant of this arg. 393 simple_arg.arg_type = arg_type; 394 simple_arg.arg_repetition = repetition_type; 395 396 // There is only one variant this argument could be; put it into the argument 397 // entry. 398 arg_entry.push_back(simple_arg); 399 400 // Push the data for the first argument into the m_arguments vector. 401 m_arguments.push_back(arg_entry); 402 } 403 404 int CommandObject::GetNumArgumentEntries() { return m_arguments.size(); } 405 406 CommandObject::CommandArgumentEntry * 407 CommandObject::GetArgumentEntryAtIndex(int idx) { 408 if (static_cast<size_t>(idx) < m_arguments.size()) 409 return &(m_arguments[idx]); 410 411 return nullptr; 412 } 413 414 const CommandObject::ArgumentTableEntry * 415 CommandObject::FindArgumentDataByType(CommandArgumentType arg_type) { 416 for (int i = 0; i < eArgTypeLastArg; ++i) 417 if (g_argument_table[i].arg_type == arg_type) 418 return &(g_argument_table[i]); 419 420 return nullptr; 421 } 422 423 void CommandObject::GetArgumentHelp(Stream &str, CommandArgumentType arg_type, 424 CommandInterpreter &interpreter) { 425 const ArgumentTableEntry *entry = &(g_argument_table[arg_type]); 426 427 // The table is *supposed* to be kept in arg_type order, but someone *could* 428 // have messed it up... 429 430 if (entry->arg_type != arg_type) 431 entry = CommandObject::FindArgumentDataByType(arg_type); 432 433 if (!entry) 434 return; 435 436 StreamString name_str; 437 name_str.Printf("<%s>", entry->arg_name); 438 439 if (entry->help_function) { 440 llvm::StringRef help_text = entry->help_function(); 441 if (!entry->help_function.self_formatting) { 442 interpreter.OutputFormattedHelpText(str, name_str.GetString(), "--", 443 help_text, name_str.GetSize()); 444 } else { 445 interpreter.OutputHelpText(str, name_str.GetString(), "--", help_text, 446 name_str.GetSize()); 447 } 448 } else { 449 interpreter.OutputFormattedHelpText(str, name_str.GetString(), "--", 450 entry->help_text, name_str.GetSize()); 451 452 // Print enum values and their description if any. 453 OptionEnumValues enum_values = g_argument_table[arg_type].enum_values; 454 if (!enum_values.empty()) { 455 str.EOL(); 456 size_t longest = 0; 457 for (const OptionEnumValueElement &element : enum_values) 458 longest = 459 std::max(longest, llvm::StringRef(element.string_value).size()); 460 str.IndentMore(5); 461 for (const OptionEnumValueElement &element : enum_values) { 462 str.Indent(); 463 interpreter.OutputHelpText(str, element.string_value, ":", 464 element.usage, longest); 465 } 466 str.IndentLess(5); 467 str.EOL(); 468 } 469 } 470 } 471 472 const char *CommandObject::GetArgumentName(CommandArgumentType arg_type) { 473 const ArgumentTableEntry *entry = &(g_argument_table[arg_type]); 474 475 // The table is *supposed* to be kept in arg_type order, but someone *could* 476 // have messed it up... 477 478 if (entry->arg_type != arg_type) 479 entry = CommandObject::FindArgumentDataByType(arg_type); 480 481 if (entry) 482 return entry->arg_name; 483 484 return nullptr; 485 } 486 487 bool CommandObject::IsPairType(ArgumentRepetitionType arg_repeat_type) { 488 return (arg_repeat_type == eArgRepeatPairPlain) || 489 (arg_repeat_type == eArgRepeatPairOptional) || 490 (arg_repeat_type == eArgRepeatPairPlus) || 491 (arg_repeat_type == eArgRepeatPairStar) || 492 (arg_repeat_type == eArgRepeatPairRange) || 493 (arg_repeat_type == eArgRepeatPairRangeOptional); 494 } 495 496 std::optional<ArgumentRepetitionType> 497 CommandObject::ArgRepetitionFromString(llvm::StringRef string) { 498 return llvm::StringSwitch<ArgumentRepetitionType>(string) 499 .Case("plain", eArgRepeatPlain) 500 .Case("optional", eArgRepeatOptional) 501 .Case("plus", eArgRepeatPlus) 502 .Case("star", eArgRepeatStar) 503 .Case("range", eArgRepeatRange) 504 .Case("pair-plain", eArgRepeatPairPlain) 505 .Case("pair-optional", eArgRepeatPairOptional) 506 .Case("pair-plus", eArgRepeatPairPlus) 507 .Case("pair-star", eArgRepeatPairStar) 508 .Case("pair-range", eArgRepeatPairRange) 509 .Case("pair-range-optional", eArgRepeatPairRangeOptional) 510 .Default({}); 511 } 512 513 static CommandObject::CommandArgumentEntry 514 OptSetFiltered(uint32_t opt_set_mask, 515 CommandObject::CommandArgumentEntry &cmd_arg_entry) { 516 CommandObject::CommandArgumentEntry ret_val; 517 for (unsigned i = 0; i < cmd_arg_entry.size(); ++i) 518 if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association) 519 ret_val.push_back(cmd_arg_entry[i]); 520 return ret_val; 521 } 522 523 // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means 524 // take all the argument data into account. On rare cases where some argument 525 // sticks with certain option sets, this function returns the option set 526 // filtered args. 527 void CommandObject::GetFormattedCommandArguments(Stream &str, 528 uint32_t opt_set_mask) { 529 int num_args = m_arguments.size(); 530 for (int i = 0; i < num_args; ++i) { 531 if (i > 0) 532 str.Printf(" "); 533 CommandArgumentEntry arg_entry = 534 opt_set_mask == LLDB_OPT_SET_ALL 535 ? m_arguments[i] 536 : OptSetFiltered(opt_set_mask, m_arguments[i]); 537 // This argument is not associated with the current option set, so skip it. 538 if (arg_entry.empty()) 539 continue; 540 int num_alternatives = arg_entry.size(); 541 542 if ((num_alternatives == 2) && IsPairType(arg_entry[0].arg_repetition)) { 543 const char *first_name = GetArgumentName(arg_entry[0].arg_type); 544 const char *second_name = GetArgumentName(arg_entry[1].arg_type); 545 switch (arg_entry[0].arg_repetition) { 546 case eArgRepeatPairPlain: 547 str.Printf("<%s> <%s>", first_name, second_name); 548 break; 549 case eArgRepeatPairOptional: 550 str.Printf("[<%s> <%s>]", first_name, second_name); 551 break; 552 case eArgRepeatPairPlus: 553 str.Printf("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, 554 first_name, second_name); 555 break; 556 case eArgRepeatPairStar: 557 str.Printf("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, 558 first_name, second_name); 559 break; 560 case eArgRepeatPairRange: 561 str.Printf("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, 562 first_name, second_name); 563 break; 564 case eArgRepeatPairRangeOptional: 565 str.Printf("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, 566 first_name, second_name); 567 break; 568 // Explicitly test for all the rest of the cases, so if new types get 569 // added we will notice the missing case statement(s). 570 case eArgRepeatPlain: 571 case eArgRepeatOptional: 572 case eArgRepeatPlus: 573 case eArgRepeatStar: 574 case eArgRepeatRange: 575 // These should not be reached, as they should fail the IsPairType test 576 // above. 577 break; 578 } 579 } else { 580 StreamString names; 581 for (int j = 0; j < num_alternatives; ++j) { 582 if (j > 0) 583 names.Printf(" | "); 584 names.Printf("%s", GetArgumentName(arg_entry[j].arg_type)); 585 } 586 587 std::string name_str = std::string(names.GetString()); 588 switch (arg_entry[0].arg_repetition) { 589 case eArgRepeatPlain: 590 str.Printf("<%s>", name_str.c_str()); 591 break; 592 case eArgRepeatPlus: 593 str.Printf("<%s> [<%s> [...]]", name_str.c_str(), name_str.c_str()); 594 break; 595 case eArgRepeatStar: 596 str.Printf("[<%s> [<%s> [...]]]", name_str.c_str(), name_str.c_str()); 597 break; 598 case eArgRepeatOptional: 599 str.Printf("[<%s>]", name_str.c_str()); 600 break; 601 case eArgRepeatRange: 602 str.Printf("<%s_1> .. <%s_n>", name_str.c_str(), name_str.c_str()); 603 break; 604 // Explicitly test for all the rest of the cases, so if new types get 605 // added we will notice the missing case statement(s). 606 case eArgRepeatPairPlain: 607 case eArgRepeatPairOptional: 608 case eArgRepeatPairPlus: 609 case eArgRepeatPairStar: 610 case eArgRepeatPairRange: 611 case eArgRepeatPairRangeOptional: 612 // These should not be hit, as they should pass the IsPairType test 613 // above, and control should have gone into the other branch of the if 614 // statement. 615 break; 616 } 617 } 618 } 619 } 620 621 CommandArgumentType 622 CommandObject::LookupArgumentName(llvm::StringRef arg_name) { 623 CommandArgumentType return_type = eArgTypeLastArg; 624 625 arg_name = arg_name.ltrim('<').rtrim('>'); 626 627 for (int i = 0; i < eArgTypeLastArg; ++i) 628 if (arg_name == g_argument_table[i].arg_name) 629 return_type = g_argument_table[i].arg_type; 630 631 return return_type; 632 } 633 634 void CommandObject::FormatLongHelpText(Stream &output_strm, 635 llvm::StringRef long_help) { 636 CommandInterpreter &interpreter = GetCommandInterpreter(); 637 std::stringstream lineStream{std::string(long_help)}; 638 std::string line; 639 while (std::getline(lineStream, line)) { 640 if (line.empty()) { 641 output_strm << "\n"; 642 continue; 643 } 644 size_t result = line.find_first_not_of(" \t"); 645 if (result == std::string::npos) { 646 result = 0; 647 } 648 std::string whitespace_prefix = line.substr(0, result); 649 std::string remainder = line.substr(result); 650 interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix, 651 remainder); 652 } 653 } 654 655 void CommandObject::GenerateHelpText(CommandReturnObject &result) { 656 GenerateHelpText(result.GetOutputStream()); 657 658 result.SetStatus(eReturnStatusSuccessFinishNoResult); 659 } 660 661 void CommandObject::GenerateHelpText(Stream &output_strm) { 662 CommandInterpreter &interpreter = GetCommandInterpreter(); 663 std::string help_text(GetHelp()); 664 if (WantsRawCommandString()) { 665 help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); 666 } 667 interpreter.OutputFormattedHelpText(output_strm, "", help_text); 668 output_strm << "\nSyntax: " << GetSyntax() << "\n"; 669 Options *options = GetOptions(); 670 if (options != nullptr) { 671 options->GenerateOptionUsage( 672 output_strm, *this, 673 GetCommandInterpreter().GetDebugger().GetTerminalWidth()); 674 } 675 llvm::StringRef long_help = GetHelpLong(); 676 if (!long_help.empty()) { 677 FormatLongHelpText(output_strm, long_help); 678 } 679 if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0) { 680 if (WantsRawCommandString() && !WantsCompletion()) { 681 // Emit the message about using ' -- ' between the end of the command 682 // options and the raw input conditionally, i.e., only if the command 683 // object does not want completion. 684 interpreter.OutputFormattedHelpText( 685 output_strm, "", "", 686 "\nImportant Note: Because this command takes 'raw' input, if you " 687 "use any command options" 688 " you must use ' -- ' between the end of the command options and the " 689 "beginning of the raw input.", 690 1); 691 } else if (GetNumArgumentEntries() > 0) { 692 // Also emit a warning about using "--" in case you are using a command 693 // that takes options and arguments. 694 interpreter.OutputFormattedHelpText( 695 output_strm, "", "", 696 "\nThis command takes options and free-form arguments. If your " 697 "arguments resemble" 698 " option specifiers (i.e., they start with a - or --), you must use " 699 "' -- ' between" 700 " the end of the command options and the beginning of the arguments.", 701 1); 702 } 703 } 704 } 705 706 void CommandObject::AddIDsArgumentData(CommandObject::IDType type) { 707 CommandArgumentEntry arg; 708 CommandArgumentData id_arg; 709 CommandArgumentData id_range_arg; 710 711 // Create the first variant for the first (and only) argument for this 712 // command. 713 switch (type) { 714 case eBreakpointArgs: 715 id_arg.arg_type = eArgTypeBreakpointID; 716 id_range_arg.arg_type = eArgTypeBreakpointIDRange; 717 break; 718 case eWatchpointArgs: 719 id_arg.arg_type = eArgTypeWatchpointID; 720 id_range_arg.arg_type = eArgTypeWatchpointIDRange; 721 break; 722 } 723 id_arg.arg_repetition = eArgRepeatOptional; 724 id_range_arg.arg_repetition = eArgRepeatOptional; 725 726 // The first (and only) argument for this command could be either an id or an 727 // id_range. Push both variants into the entry for the first argument for 728 // this command. 729 arg.push_back(id_arg); 730 arg.push_back(id_range_arg); 731 m_arguments.push_back(arg); 732 } 733 734 const char *CommandObject::GetArgumentTypeAsCString( 735 const lldb::CommandArgumentType arg_type) { 736 assert(arg_type < eArgTypeLastArg && 737 "Invalid argument type passed to GetArgumentTypeAsCString"); 738 return g_argument_table[arg_type].arg_name; 739 } 740 741 const char *CommandObject::GetArgumentDescriptionAsCString( 742 const lldb::CommandArgumentType arg_type) { 743 assert(arg_type < eArgTypeLastArg && 744 "Invalid argument type passed to GetArgumentDescriptionAsCString"); 745 return g_argument_table[arg_type].help_text; 746 } 747 748 Target &CommandObject::GetDummyTarget() { 749 return m_interpreter.GetDebugger().GetDummyTarget(); 750 } 751 752 Target &CommandObject::GetTarget() { 753 // Prefer the frozen execution context in the command object. 754 if (Target *target = m_exe_ctx.GetTargetPtr()) 755 return *target; 756 757 // Fallback to the command interpreter's execution context in case we get 758 // called after DoExecute has finished. For example, when doing multi-line 759 // expression that uses an input reader or breakpoint callbacks. 760 if (Target *target = m_interpreter.GetExecutionContext().GetTargetPtr()) 761 return *target; 762 763 // Finally, if we have no other target, get the selected target. 764 if (TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget()) 765 return *target_sp; 766 767 // We only have the dummy target. 768 return GetDummyTarget(); 769 } 770 771 Thread *CommandObject::GetDefaultThread() { 772 Thread *thread_to_use = m_exe_ctx.GetThreadPtr(); 773 if (thread_to_use) 774 return thread_to_use; 775 776 Process *process = m_exe_ctx.GetProcessPtr(); 777 if (!process) { 778 Target *target = m_exe_ctx.GetTargetPtr(); 779 if (!target) { 780 target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 781 } 782 if (target) 783 process = target->GetProcessSP().get(); 784 } 785 786 if (process) 787 return process->GetThreadList().GetSelectedThread().get(); 788 else 789 return nullptr; 790 } 791 792 void CommandObjectParsed::Execute(const char *args_string, 793 CommandReturnObject &result) { 794 bool handled = false; 795 Args cmd_args(args_string); 796 if (HasOverrideCallback()) { 797 Args full_args(GetCommandName()); 798 full_args.AppendArguments(cmd_args); 799 handled = 800 InvokeOverrideCallback(full_args.GetConstArgumentVector(), result); 801 } 802 if (!handled) { 803 for (auto entry : llvm::enumerate(cmd_args.entries())) { 804 const Args::ArgEntry &value = entry.value(); 805 if (!value.ref().empty() && value.GetQuoteChar() == '`') { 806 // We have to put the backtick back in place for PreprocessCommand. 807 std::string opt_string = value.c_str(); 808 Status error; 809 error = m_interpreter.PreprocessToken(opt_string); 810 if (error.Success()) 811 cmd_args.ReplaceArgumentAtIndex(entry.index(), opt_string); 812 } 813 } 814 815 if (CheckRequirements(result)) { 816 if (ParseOptions(cmd_args, result)) { 817 // Call the command-specific version of 'Execute', passing it the 818 // already processed arguments. 819 if (cmd_args.GetArgumentCount() != 0 && m_arguments.empty()) { 820 result.AppendErrorWithFormatv("'{0}' doesn't take any arguments.", 821 GetCommandName()); 822 Cleanup(); 823 return; 824 } 825 m_interpreter.IncreaseCommandUsage(*this); 826 DoExecute(cmd_args, result); 827 } 828 } 829 830 Cleanup(); 831 } 832 } 833 834 void CommandObjectRaw::Execute(const char *args_string, 835 CommandReturnObject &result) { 836 bool handled = false; 837 if (HasOverrideCallback()) { 838 std::string full_command(GetCommandName()); 839 full_command += ' '; 840 full_command += args_string; 841 const char *argv[2] = {nullptr, nullptr}; 842 argv[0] = full_command.c_str(); 843 handled = InvokeOverrideCallback(argv, result); 844 } 845 if (!handled) { 846 if (CheckRequirements(result)) 847 DoExecute(args_string, result); 848 849 Cleanup(); 850 } 851 } 852