1 //===-- CommandInterpreter.h ------------------------------------*- 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 #ifndef LLDB_INTERPRETER_COMMANDINTERPRETER_H 10 #define LLDB_INTERPRETER_COMMANDINTERPRETER_H 11 12 #include "lldb/Core/Debugger.h" 13 #include "lldb/Core/IOHandler.h" 14 #include "lldb/Interpreter/CommandAlias.h" 15 #include "lldb/Interpreter/CommandHistory.h" 16 #include "lldb/Interpreter/CommandObject.h" 17 #include "lldb/Interpreter/ScriptInterpreter.h" 18 #include "lldb/Utility/Args.h" 19 #include "lldb/Utility/Broadcaster.h" 20 #include "lldb/Utility/CompletionRequest.h" 21 #include "lldb/Utility/Event.h" 22 #include "lldb/Utility/Log.h" 23 #include "lldb/Utility/StreamString.h" 24 #include "lldb/Utility/StringList.h" 25 #include "lldb/lldb-forward.h" 26 #include "lldb/lldb-private.h" 27 28 #include <mutex> 29 #include <stack> 30 31 namespace lldb_private { 32 class CommandInterpreter; 33 34 class CommandInterpreterRunResult { 35 public: 36 CommandInterpreterRunResult() = default; 37 38 uint32_t GetNumErrors() const { return m_num_errors; } 39 40 lldb::CommandInterpreterResult GetResult() const { return m_result; } 41 42 bool IsResult(lldb::CommandInterpreterResult result) { 43 return m_result == result; 44 } 45 46 protected: 47 friend CommandInterpreter; 48 49 void IncrementNumberOfErrors() { m_num_errors++; } 50 51 void SetResult(lldb::CommandInterpreterResult result) { m_result = result; } 52 53 private: 54 int m_num_errors = 0; 55 lldb::CommandInterpreterResult m_result = 56 lldb::eCommandInterpreterResultSuccess; 57 }; 58 59 class CommandInterpreterRunOptions { 60 public: 61 /// Construct a CommandInterpreterRunOptions object. This class is used to 62 /// control all the instances where we run multiple commands, e.g. 63 /// HandleCommands, HandleCommandsFromFile, RunCommandInterpreter. 64 /// 65 /// The meanings of the options in this object are: 66 /// 67 /// \param[in] stop_on_continue 68 /// If \b true, execution will end on the first command that causes the 69 /// process in the execution context to continue. If \b false, we won't 70 /// check the execution status. 71 /// \param[in] stop_on_error 72 /// If \b true, execution will end on the first command that causes an 73 /// error. 74 /// \param[in] stop_on_crash 75 /// If \b true, when a command causes the target to run, and the end of the 76 /// run is a signal or exception, stop executing the commands. 77 /// \param[in] echo_commands 78 /// If \b true, echo the command before executing it. If \b false, execute 79 /// silently. 80 /// \param[in] echo_comments 81 /// If \b true, echo command even if it is a pure comment line. If 82 /// \b false, print no ouput in this case. This setting has an effect only 83 /// if echo_commands is \b true. 84 /// \param[in] print_results 85 /// If \b true and the command succeeds, print the results of the command 86 /// after executing it. If \b false, execute silently. 87 /// \param[in] print_errors 88 /// If \b true and the command fails, print the results of the command 89 /// after executing it. If \b false, execute silently. 90 /// \param[in] add_to_history 91 /// If \b true add the commands to the command history. If \b false, don't 92 /// add them. 93 CommandInterpreterRunOptions(LazyBool stop_on_continue, 94 LazyBool stop_on_error, LazyBool stop_on_crash, 95 LazyBool echo_commands, LazyBool echo_comments, 96 LazyBool print_results, LazyBool print_errors, 97 LazyBool add_to_history) 98 : m_stop_on_continue(stop_on_continue), m_stop_on_error(stop_on_error), 99 m_stop_on_crash(stop_on_crash), m_echo_commands(echo_commands), 100 m_echo_comment_commands(echo_comments), m_print_results(print_results), 101 m_print_errors(print_errors), m_add_to_history(add_to_history) {} 102 103 CommandInterpreterRunOptions() = default; 104 105 void SetSilent(bool silent) { 106 LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes; 107 108 m_print_results = value; 109 m_print_errors = value; 110 m_echo_commands = value; 111 m_echo_comment_commands = value; 112 m_add_to_history = value; 113 } 114 // These return the default behaviors if the behavior is not 115 // eLazyBoolCalculate. But I've also left the ivars public since for 116 // different ways of running the interpreter you might want to force 117 // different defaults... In that case, just grab the LazyBool ivars directly 118 // and do what you want with eLazyBoolCalculate. 119 bool GetStopOnContinue() const { return DefaultToNo(m_stop_on_continue); } 120 121 void SetStopOnContinue(bool stop_on_continue) { 122 m_stop_on_continue = stop_on_continue ? eLazyBoolYes : eLazyBoolNo; 123 } 124 125 bool GetStopOnError() const { return DefaultToNo(m_stop_on_error); } 126 127 void SetStopOnError(bool stop_on_error) { 128 m_stop_on_error = stop_on_error ? eLazyBoolYes : eLazyBoolNo; 129 } 130 131 bool GetStopOnCrash() const { return DefaultToNo(m_stop_on_crash); } 132 133 void SetStopOnCrash(bool stop_on_crash) { 134 m_stop_on_crash = stop_on_crash ? eLazyBoolYes : eLazyBoolNo; 135 } 136 137 bool GetEchoCommands() const { return DefaultToYes(m_echo_commands); } 138 139 void SetEchoCommands(bool echo_commands) { 140 m_echo_commands = echo_commands ? eLazyBoolYes : eLazyBoolNo; 141 } 142 143 bool GetEchoCommentCommands() const { 144 return DefaultToYes(m_echo_comment_commands); 145 } 146 147 void SetEchoCommentCommands(bool echo_comments) { 148 m_echo_comment_commands = echo_comments ? eLazyBoolYes : eLazyBoolNo; 149 } 150 151 bool GetPrintResults() const { return DefaultToYes(m_print_results); } 152 153 void SetPrintResults(bool print_results) { 154 m_print_results = print_results ? eLazyBoolYes : eLazyBoolNo; 155 } 156 157 bool GetPrintErrors() const { return DefaultToYes(m_print_errors); } 158 159 void SetPrintErrors(bool print_errors) { 160 m_print_errors = print_errors ? eLazyBoolYes : eLazyBoolNo; 161 } 162 163 bool GetAddToHistory() const { return DefaultToYes(m_add_to_history); } 164 165 void SetAddToHistory(bool add_to_history) { 166 m_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo; 167 } 168 169 bool GetAutoHandleEvents() const { 170 return DefaultToYes(m_auto_handle_events); 171 } 172 173 void SetAutoHandleEvents(bool auto_handle_events) { 174 m_auto_handle_events = auto_handle_events ? eLazyBoolYes : eLazyBoolNo; 175 } 176 177 bool GetSpawnThread() const { return DefaultToNo(m_spawn_thread); } 178 179 void SetSpawnThread(bool spawn_thread) { 180 m_spawn_thread = spawn_thread ? eLazyBoolYes : eLazyBoolNo; 181 } 182 183 LazyBool m_stop_on_continue = eLazyBoolCalculate; 184 LazyBool m_stop_on_error = eLazyBoolCalculate; 185 LazyBool m_stop_on_crash = eLazyBoolCalculate; 186 LazyBool m_echo_commands = eLazyBoolCalculate; 187 LazyBool m_echo_comment_commands = eLazyBoolCalculate; 188 LazyBool m_print_results = eLazyBoolCalculate; 189 LazyBool m_print_errors = eLazyBoolCalculate; 190 LazyBool m_add_to_history = eLazyBoolCalculate; 191 LazyBool m_auto_handle_events; 192 LazyBool m_spawn_thread; 193 194 private: 195 static bool DefaultToYes(LazyBool flag) { 196 switch (flag) { 197 case eLazyBoolNo: 198 return false; 199 default: 200 return true; 201 } 202 } 203 204 static bool DefaultToNo(LazyBool flag) { 205 switch (flag) { 206 case eLazyBoolYes: 207 return true; 208 default: 209 return false; 210 } 211 } 212 }; 213 214 class CommandInterpreter : public Broadcaster, 215 public Properties, 216 public IOHandlerDelegate { 217 public: 218 enum { 219 eBroadcastBitThreadShouldExit = (1 << 0), 220 eBroadcastBitResetPrompt = (1 << 1), 221 eBroadcastBitQuitCommandReceived = (1 << 2), // User entered quit 222 eBroadcastBitAsynchronousOutputData = (1 << 3), 223 eBroadcastBitAsynchronousErrorData = (1 << 4) 224 }; 225 226 /// Tristate boolean to manage children omission warnings. 227 enum ChildrenOmissionWarningStatus { 228 eNoOmission = 0, ///< No children were omitted. 229 eUnwarnedOmission = 1, ///< Children omitted, and not yet notified. 230 eWarnedOmission = 2 ///< Children omitted and notified. 231 }; 232 233 enum CommandTypes { 234 eCommandTypesBuiltin = 0x0001, //< native commands such as "frame" 235 eCommandTypesUserDef = 0x0002, //< scripted commands 236 eCommandTypesUserMW = 0x0004, //< multiword commands (command containers) 237 eCommandTypesAliases = 0x0008, //< aliases such as "po" 238 eCommandTypesHidden = 0x0010, //< commands prefixed with an underscore 239 eCommandTypesAllThem = 0xFFFF //< all commands 240 }; 241 242 CommandInterpreter(Debugger &debugger, bool synchronous_execution); 243 244 ~CommandInterpreter() override = default; 245 246 // These two functions fill out the Broadcaster interface: 247 248 static ConstString &GetStaticBroadcasterClass(); 249 250 ConstString &GetBroadcasterClass() const override { 251 return GetStaticBroadcasterClass(); 252 } 253 254 void SourceInitFileCwd(CommandReturnObject &result); 255 void SourceInitFileHome(CommandReturnObject &result, bool is_repl); 256 void SourceInitFileGlobal(CommandReturnObject &result); 257 258 bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, 259 bool can_replace); 260 261 Status AddUserCommand(llvm::StringRef name, 262 const lldb::CommandObjectSP &cmd_sp, bool can_replace); 263 264 lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd, 265 bool include_aliases = false) const; 266 267 CommandObject *GetCommandObject(llvm::StringRef cmd, 268 StringList *matches = nullptr, 269 StringList *descriptions = nullptr) const; 270 271 CommandObject *GetUserCommandObject(llvm::StringRef cmd, 272 StringList *matches = nullptr, 273 StringList *descriptions = nullptr) const; 274 275 /// Determine whether a root level, built-in command with this name exists. 276 bool CommandExists(llvm::StringRef cmd) const; 277 278 /// Determine whether an alias command with this name exists 279 bool AliasExists(llvm::StringRef cmd) const; 280 281 /// Determine whether a root-level user command with this name exists. 282 bool UserCommandExists(llvm::StringRef cmd) const; 283 284 /// Determine whether a root-level user multiword command with this name 285 /// exists. 286 bool UserMultiwordCommandExists(llvm::StringRef cmd) const; 287 288 /// Look up the command pointed to by path encoded in the arguments of 289 /// the incoming command object. If all the path components exist 290 /// and are all actual commands - not aliases, and the leaf command is a 291 /// multiword command, return the command. Otherwise return nullptr, and put 292 /// a useful diagnostic in the Status object. 293 /// 294 /// \param[in] path 295 /// An Args object holding the path in its arguments 296 /// \param[in] leaf_is_command 297 /// If true, return the container of the leaf name rather than looking up 298 /// the whole path as a leaf command. The leaf needn't exist in this case. 299 /// \param[in,out] result 300 /// If the path is not found, this error shows where we got off track. 301 /// \return 302 /// If found, a pointer to the CommandObjectMultiword pointed to by path, 303 /// or to the container of the leaf element is is_leaf_command. 304 /// Returns nullptr under two circumstances: 305 /// 1) The command in not found (check error.Fail) 306 /// 2) is_leaf is true and the path has only a leaf. We don't have a 307 /// dummy "contains everything MWC, so we return null here, but 308 /// in this case error.Success is true. 309 310 CommandObjectMultiword *VerifyUserMultiwordCmdPath(Args &path, 311 bool leaf_is_command, 312 Status &result); 313 314 CommandAlias *AddAlias(llvm::StringRef alias_name, 315 lldb::CommandObjectSP &command_obj_sp, 316 llvm::StringRef args_string = llvm::StringRef()); 317 318 // Remove a command if it is removable (python or regex command) 319 bool RemoveCommand(llvm::StringRef cmd); 320 321 bool RemoveAlias(llvm::StringRef alias_name); 322 323 bool GetAliasFullName(llvm::StringRef cmd, std::string &full_name) const; 324 325 bool RemoveUserMultiword(llvm::StringRef multiword_name); 326 327 // Do we want to allow top-level user multiword commands to be deleted? 328 void RemoveAllUserMultiword() { m_user_mw_dict.clear(); } 329 330 bool RemoveUser(llvm::StringRef alias_name); 331 332 void RemoveAllUser() { m_user_dict.clear(); } 333 334 const CommandAlias *GetAlias(llvm::StringRef alias_name) const; 335 336 CommandObject *BuildAliasResult(llvm::StringRef alias_name, 337 std::string &raw_input_string, 338 std::string &alias_result, 339 CommandReturnObject &result); 340 341 bool HandleCommand(const char *command_line, LazyBool add_to_history, 342 const ExecutionContext &override_context, 343 CommandReturnObject &result); 344 345 bool HandleCommand(const char *command_line, LazyBool add_to_history, 346 CommandReturnObject &result); 347 348 bool WasInterrupted() const; 349 350 /// Execute a list of commands in sequence. 351 /// 352 /// \param[in] commands 353 /// The list of commands to execute. 354 /// \param[in,out] context 355 /// The execution context in which to run the commands. 356 /// \param[in] options 357 /// This object holds the options used to control when to stop, whether to 358 /// execute commands, 359 /// etc. 360 /// \param[out] result 361 /// This is marked as succeeding with no output if all commands execute 362 /// safely, 363 /// and failed with some explanation if we aborted executing the commands 364 /// at some point. 365 void HandleCommands(const StringList &commands, 366 const ExecutionContext &context, 367 const CommandInterpreterRunOptions &options, 368 CommandReturnObject &result); 369 370 void HandleCommands(const StringList &commands, 371 const CommandInterpreterRunOptions &options, 372 CommandReturnObject &result); 373 374 /// Execute a list of commands from a file. 375 /// 376 /// \param[in] file 377 /// The file from which to read in commands. 378 /// \param[in,out] context 379 /// The execution context in which to run the commands. 380 /// \param[in] options 381 /// This object holds the options used to control when to stop, whether to 382 /// execute commands, 383 /// etc. 384 /// \param[out] result 385 /// This is marked as succeeding with no output if all commands execute 386 /// safely, 387 /// and failed with some explanation if we aborted executing the commands 388 /// at some point. 389 void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context, 390 const CommandInterpreterRunOptions &options, 391 CommandReturnObject &result); 392 393 void HandleCommandsFromFile(FileSpec &file, 394 const CommandInterpreterRunOptions &options, 395 CommandReturnObject &result); 396 397 CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line); 398 399 /// Returns the auto-suggestion string that should be added to the given 400 /// command line. 401 llvm::Optional<std::string> GetAutoSuggestionForCommand(llvm::StringRef line); 402 403 // This handles command line completion. 404 void HandleCompletion(CompletionRequest &request); 405 406 // This version just returns matches, and doesn't compute the substring. It 407 // is here so the Help command can call it for the first argument. 408 void HandleCompletionMatches(CompletionRequest &request); 409 410 int GetCommandNamesMatchingPartialString(const char *cmd_cstr, 411 bool include_aliases, 412 StringList &matches, 413 StringList &descriptions); 414 415 void GetHelp(CommandReturnObject &result, 416 uint32_t types = eCommandTypesAllThem); 417 418 void GetAliasHelp(const char *alias_name, StreamString &help_string); 419 420 void OutputFormattedHelpText(Stream &strm, llvm::StringRef prefix, 421 llvm::StringRef help_text); 422 423 void OutputFormattedHelpText(Stream &stream, llvm::StringRef command_word, 424 llvm::StringRef separator, 425 llvm::StringRef help_text, size_t max_word_len); 426 427 // this mimics OutputFormattedHelpText but it does perform a much simpler 428 // formatting, basically ensuring line alignment. This is only good if you 429 // have some complicated layout for your help text and want as little help as 430 // reasonable in properly displaying it. Most of the times, you simply want 431 // to type some text and have it printed in a reasonable way on screen. If 432 // so, use OutputFormattedHelpText 433 void OutputHelpText(Stream &stream, llvm::StringRef command_word, 434 llvm::StringRef separator, llvm::StringRef help_text, 435 uint32_t max_word_len); 436 437 Debugger &GetDebugger() { return m_debugger; } 438 439 ExecutionContext GetExecutionContext() const; 440 441 lldb::PlatformSP GetPlatform(bool prefer_target_platform); 442 443 const char *ProcessEmbeddedScriptCommands(const char *arg); 444 445 void UpdatePrompt(llvm::StringRef prompt); 446 447 bool Confirm(llvm::StringRef message, bool default_answer); 448 449 void LoadCommandDictionary(); 450 451 void Initialize(); 452 453 void Clear(); 454 455 bool HasCommands() const; 456 457 bool HasAliases() const; 458 459 bool HasUserCommands() const; 460 461 bool HasUserMultiwordCommands() const; 462 463 bool HasAliasOptions() const; 464 465 void BuildAliasCommandArgs(CommandObject *alias_cmd_obj, 466 const char *alias_name, Args &cmd_args, 467 std::string &raw_input_string, 468 CommandReturnObject &result); 469 470 /// Picks the number out of a string of the form "%NNN", otherwise return 0. 471 int GetOptionArgumentPosition(const char *in_string); 472 473 void SkipLLDBInitFiles(bool skip_lldbinit_files) { 474 m_skip_lldbinit_files = skip_lldbinit_files; 475 } 476 477 void SkipAppInitFiles(bool skip_app_init_files) { 478 m_skip_app_init_files = skip_app_init_files; 479 } 480 481 bool GetSynchronous(); 482 483 void FindCommandsForApropos(llvm::StringRef word, StringList &commands_found, 484 StringList &commands_help, 485 bool search_builtin_commands, 486 bool search_user_commands, 487 bool search_alias_commands, 488 bool search_user_mw_commands); 489 490 bool GetBatchCommandMode() { return m_batch_command_mode; } 491 492 bool SetBatchCommandMode(bool value) { 493 const bool old_value = m_batch_command_mode; 494 m_batch_command_mode = value; 495 return old_value; 496 } 497 498 void ChildrenTruncated() { 499 if (m_truncation_warning == eNoOmission) 500 m_truncation_warning = eUnwarnedOmission; 501 } 502 503 void SetReachedMaximumDepth() { 504 if (m_max_depth_warning == eNoOmission) 505 m_max_depth_warning = eUnwarnedOmission; 506 } 507 508 void PrintWarningsIfNecessary(Stream &s, const std::string &cmd_name) { 509 if (m_truncation_warning == eUnwarnedOmission) { 510 s.Printf("*** Some of the displayed variables have more members than the " 511 "debugger will show by default. To show all of them, you can " 512 "either use the --show-all-children option to %s or raise the " 513 "limit by changing the target.max-children-count setting.\n", 514 cmd_name.c_str()); 515 m_truncation_warning = eWarnedOmission; 516 } 517 518 if (m_max_depth_warning == eUnwarnedOmission) { 519 s.Printf("*** Some of the displayed variables have a greater depth of " 520 "members than the debugger will show by default. To increase " 521 "the limit, use the --depth option to %s, or raise the limit by " 522 "changing the target.max-children-depth setting.\n", 523 cmd_name.c_str()); 524 m_max_depth_warning = eWarnedOmission; 525 } 526 } 527 528 CommandHistory &GetCommandHistory() { return m_command_history; } 529 530 bool IsActive(); 531 532 CommandInterpreterRunResult 533 RunCommandInterpreter(CommandInterpreterRunOptions &options); 534 535 void GetLLDBCommandsFromIOHandler(const char *prompt, 536 IOHandlerDelegate &delegate, 537 void *baton = nullptr); 538 539 void GetPythonCommandsFromIOHandler(const char *prompt, 540 IOHandlerDelegate &delegate, 541 void *baton = nullptr); 542 543 const char *GetCommandPrefix(); 544 545 // Properties 546 bool GetExpandRegexAliases() const; 547 548 bool GetPromptOnQuit() const; 549 void SetPromptOnQuit(bool enable); 550 551 bool GetSaveSessionOnQuit() const; 552 void SetSaveSessionOnQuit(bool enable); 553 554 FileSpec GetSaveSessionDirectory() const; 555 void SetSaveSessionDirectory(llvm::StringRef path); 556 557 bool GetEchoCommands() const; 558 void SetEchoCommands(bool enable); 559 560 bool GetEchoCommentCommands() const; 561 void SetEchoCommentCommands(bool enable); 562 563 bool GetRepeatPreviousCommand() const; 564 565 bool GetRequireCommandOverwrite() const; 566 567 const CommandObject::CommandMap &GetUserCommands() const { 568 return m_user_dict; 569 } 570 571 const CommandObject::CommandMap &GetUserMultiwordCommands() const { 572 return m_user_mw_dict; 573 } 574 575 const CommandObject::CommandMap &GetCommands() const { 576 return m_command_dict; 577 } 578 579 const CommandObject::CommandMap &GetAliases() const { return m_alias_dict; } 580 581 /// Specify if the command interpreter should allow that the user can 582 /// specify a custom exit code when calling 'quit'. 583 void AllowExitCodeOnQuit(bool allow); 584 585 /// Sets the exit code for the quit command. 586 /// \param[in] exit_code 587 /// The exit code that the driver should return on exit. 588 /// \return True if the exit code was successfully set; false if the 589 /// interpreter doesn't allow custom exit codes. 590 /// \see AllowExitCodeOnQuit 591 LLVM_NODISCARD bool SetQuitExitCode(int exit_code); 592 593 /// Returns the exit code that the user has specified when running the 594 /// 'quit' command. 595 /// \param[out] exited 596 /// Set to true if the user has called quit with a custom exit code. 597 int GetQuitExitCode(bool &exited) const; 598 599 void ResolveCommand(const char *command_line, CommandReturnObject &result); 600 601 bool GetStopCmdSourceOnError() const; 602 603 lldb::IOHandlerSP 604 GetIOHandler(bool force_create = false, 605 CommandInterpreterRunOptions *options = nullptr); 606 607 bool GetSpaceReplPrompts() const; 608 609 /// Save the current debugger session transcript to a file on disk. 610 /// \param output_file 611 /// The file path to which the session transcript will be written. Since 612 /// the argument is optional, an arbitrary temporary file will be create 613 /// when no argument is passed. 614 /// \param result 615 /// This is used to pass function output and error messages. 616 /// \return \b true if the session transcript was successfully written to 617 /// disk, \b false otherwise. 618 bool SaveTranscript(CommandReturnObject &result, 619 llvm::Optional<std::string> output_file = llvm::None); 620 621 FileSpec GetCurrentSourceDir(); 622 623 bool IsInteractive(); 624 625 bool IOHandlerInterrupt(IOHandler &io_handler) override; 626 627 protected: 628 friend class Debugger; 629 630 // IOHandlerDelegate functions 631 void IOHandlerInputComplete(IOHandler &io_handler, 632 std::string &line) override; 633 634 ConstString IOHandlerGetControlSequence(char ch) override { 635 if (ch == 'd') 636 return ConstString("quit\n"); 637 return ConstString(); 638 } 639 640 void GetProcessOutput(); 641 642 bool DidProcessStopAbnormally() const; 643 644 void SetSynchronous(bool value); 645 646 lldb::CommandObjectSP GetCommandSP(llvm::StringRef cmd, 647 bool include_aliases = true, 648 bool exact = true, 649 StringList *matches = nullptr, 650 StringList *descriptions = nullptr) const; 651 652 private: 653 void OverrideExecutionContext(const ExecutionContext &override_context); 654 655 void RestoreExecutionContext(); 656 657 Status PreprocessCommand(std::string &command); 658 659 void SourceInitFile(FileSpec file, CommandReturnObject &result); 660 661 // Completely resolves aliases and abbreviations, returning a pointer to the 662 // final command object and updating command_line to the fully substituted 663 // and translated command. 664 CommandObject *ResolveCommandImpl(std::string &command_line, 665 CommandReturnObject &result); 666 667 void FindCommandsForApropos(llvm::StringRef word, StringList &commands_found, 668 StringList &commands_help, 669 const CommandObject::CommandMap &command_map); 670 671 // An interruptible wrapper around the stream output 672 void PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str, 673 bool is_stdout); 674 675 bool EchoCommandNonInteractive(llvm::StringRef line, 676 const Flags &io_handler_flags) const; 677 678 // A very simple state machine which models the command handling transitions 679 enum class CommandHandlingState { 680 eIdle, 681 eInProgress, 682 eInterrupted, 683 }; 684 685 std::atomic<CommandHandlingState> m_command_state{ 686 CommandHandlingState::eIdle}; 687 688 int m_iohandler_nesting_level = 0; 689 690 void StartHandlingCommand(); 691 void FinishHandlingCommand(); 692 bool InterruptCommand(); 693 694 Debugger &m_debugger; // The debugger session that this interpreter is 695 // associated with 696 // Execution contexts that were temporarily set by some of HandleCommand* 697 // overloads. 698 std::stack<ExecutionContext> m_overriden_exe_contexts; 699 bool m_synchronous_execution; 700 bool m_skip_lldbinit_files; 701 bool m_skip_app_init_files; 702 CommandObject::CommandMap m_command_dict; // Stores basic built-in commands 703 // (they cannot be deleted, removed 704 // or overwritten). 705 CommandObject::CommandMap 706 m_alias_dict; // Stores user aliases/abbreviations for commands 707 CommandObject::CommandMap m_user_dict; // Stores user-defined commands 708 CommandObject::CommandMap 709 m_user_mw_dict; // Stores user-defined multiword commands 710 CommandHistory m_command_history; 711 std::string m_repeat_command; // Stores the command that will be executed for 712 // an empty command string. 713 lldb::IOHandlerSP m_command_io_handler_sp; 714 char m_comment_char; 715 bool m_batch_command_mode; 716 /// Whether we truncated a value's list of children and whether the user has 717 /// been told. 718 ChildrenOmissionWarningStatus m_truncation_warning; 719 /// Whether we reached the maximum child nesting depth and whether the user 720 /// has been told. 721 ChildrenOmissionWarningStatus m_max_depth_warning; 722 723 // FIXME: Stop using this to control adding to the history and then replace 724 // this with m_command_source_dirs.size(). 725 uint32_t m_command_source_depth; 726 /// A stack of directory paths. When not empty, the last one is the directory 727 /// of the file that's currently sourced. 728 std::vector<FileSpec> m_command_source_dirs; 729 std::vector<uint32_t> m_command_source_flags; 730 CommandInterpreterRunResult m_result; 731 732 // The exit code the user has requested when calling the 'quit' command. 733 // No value means the user hasn't set a custom exit code so far. 734 llvm::Optional<int> m_quit_exit_code; 735 // If the driver is accepts custom exit codes for the 'quit' command. 736 bool m_allow_exit_code = false; 737 738 StreamString m_transcript_stream; 739 }; 740 741 } // namespace lldb_private 742 743 #endif // LLDB_INTERPRETER_COMMANDINTERPRETER_H 744