File indexing completed on 2026-05-10 08:42:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_INTERPRETER_COMMANDINTERPRETER_H
0010 #define LLDB_INTERPRETER_COMMANDINTERPRETER_H
0011
0012 #include "lldb/Core/Debugger.h"
0013 #include "lldb/Core/IOHandler.h"
0014 #include "lldb/Interpreter/CommandAlias.h"
0015 #include "lldb/Interpreter/CommandHistory.h"
0016 #include "lldb/Interpreter/CommandObject.h"
0017 #include "lldb/Interpreter/ScriptInterpreter.h"
0018 #include "lldb/Utility/Args.h"
0019 #include "lldb/Utility/Broadcaster.h"
0020 #include "lldb/Utility/CompletionRequest.h"
0021 #include "lldb/Utility/Event.h"
0022 #include "lldb/Utility/Log.h"
0023 #include "lldb/Utility/StreamString.h"
0024 #include "lldb/Utility/StringList.h"
0025 #include "lldb/Utility/StructuredData.h"
0026 #include "lldb/lldb-forward.h"
0027 #include "lldb/lldb-private.h"
0028
0029 #include <mutex>
0030 #include <optional>
0031 #include <stack>
0032 #include <unordered_map>
0033
0034 namespace lldb_private {
0035 class CommandInterpreter;
0036
0037 class CommandInterpreterRunResult {
0038 public:
0039 CommandInterpreterRunResult() = default;
0040
0041 uint32_t GetNumErrors() const { return m_num_errors; }
0042
0043 lldb::CommandInterpreterResult GetResult() const { return m_result; }
0044
0045 bool IsResult(lldb::CommandInterpreterResult result) {
0046 return m_result == result;
0047 }
0048
0049 protected:
0050 friend CommandInterpreter;
0051
0052 void IncrementNumberOfErrors() { m_num_errors++; }
0053
0054 void SetResult(lldb::CommandInterpreterResult result) { m_result = result; }
0055
0056 private:
0057 int m_num_errors = 0;
0058 lldb::CommandInterpreterResult m_result =
0059 lldb::eCommandInterpreterResultSuccess;
0060 };
0061
0062 class CommandInterpreterRunOptions {
0063 public:
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 CommandInterpreterRunOptions(LazyBool stop_on_continue,
0100 LazyBool stop_on_error, LazyBool stop_on_crash,
0101 LazyBool echo_commands, LazyBool echo_comments,
0102 LazyBool print_results, LazyBool print_errors,
0103 LazyBool add_to_history,
0104 LazyBool handle_repeats)
0105 : m_stop_on_continue(stop_on_continue), m_stop_on_error(stop_on_error),
0106 m_stop_on_crash(stop_on_crash), m_echo_commands(echo_commands),
0107 m_echo_comment_commands(echo_comments), m_print_results(print_results),
0108 m_print_errors(print_errors), m_add_to_history(add_to_history),
0109 m_allow_repeats(handle_repeats) {}
0110
0111 CommandInterpreterRunOptions() = default;
0112
0113 void SetSilent(bool silent) {
0114 LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes;
0115
0116 m_print_results = value;
0117 m_print_errors = value;
0118 m_echo_commands = value;
0119 m_echo_comment_commands = value;
0120 m_add_to_history = value;
0121 }
0122
0123
0124
0125
0126
0127 bool GetStopOnContinue() const { return DefaultToNo(m_stop_on_continue); }
0128
0129 void SetStopOnContinue(bool stop_on_continue) {
0130 m_stop_on_continue = stop_on_continue ? eLazyBoolYes : eLazyBoolNo;
0131 }
0132
0133 bool GetStopOnError() const { return DefaultToNo(m_stop_on_error); }
0134
0135 void SetStopOnError(bool stop_on_error) {
0136 m_stop_on_error = stop_on_error ? eLazyBoolYes : eLazyBoolNo;
0137 }
0138
0139 bool GetStopOnCrash() const { return DefaultToNo(m_stop_on_crash); }
0140
0141 void SetStopOnCrash(bool stop_on_crash) {
0142 m_stop_on_crash = stop_on_crash ? eLazyBoolYes : eLazyBoolNo;
0143 }
0144
0145 bool GetEchoCommands() const { return DefaultToYes(m_echo_commands); }
0146
0147 void SetEchoCommands(bool echo_commands) {
0148 m_echo_commands = echo_commands ? eLazyBoolYes : eLazyBoolNo;
0149 }
0150
0151 bool GetEchoCommentCommands() const {
0152 return DefaultToYes(m_echo_comment_commands);
0153 }
0154
0155 void SetEchoCommentCommands(bool echo_comments) {
0156 m_echo_comment_commands = echo_comments ? eLazyBoolYes : eLazyBoolNo;
0157 }
0158
0159 bool GetPrintResults() const { return DefaultToYes(m_print_results); }
0160
0161 void SetPrintResults(bool print_results) {
0162 m_print_results = print_results ? eLazyBoolYes : eLazyBoolNo;
0163 }
0164
0165 bool GetPrintErrors() const { return DefaultToYes(m_print_errors); }
0166
0167 void SetPrintErrors(bool print_errors) {
0168 m_print_errors = print_errors ? eLazyBoolYes : eLazyBoolNo;
0169 }
0170
0171 bool GetAddToHistory() const { return DefaultToYes(m_add_to_history); }
0172
0173 void SetAddToHistory(bool add_to_history) {
0174 m_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
0175 }
0176
0177 bool GetAutoHandleEvents() const {
0178 return DefaultToYes(m_auto_handle_events);
0179 }
0180
0181 void SetAutoHandleEvents(bool auto_handle_events) {
0182 m_auto_handle_events = auto_handle_events ? eLazyBoolYes : eLazyBoolNo;
0183 }
0184
0185 bool GetSpawnThread() const { return DefaultToNo(m_spawn_thread); }
0186
0187 void SetSpawnThread(bool spawn_thread) {
0188 m_spawn_thread = spawn_thread ? eLazyBoolYes : eLazyBoolNo;
0189 }
0190
0191 bool GetAllowRepeats() const { return DefaultToNo(m_allow_repeats); }
0192
0193 void SetAllowRepeats(bool allow_repeats) {
0194 m_allow_repeats = allow_repeats ? eLazyBoolYes : eLazyBoolNo;
0195 }
0196
0197 LazyBool m_stop_on_continue = eLazyBoolCalculate;
0198 LazyBool m_stop_on_error = eLazyBoolCalculate;
0199 LazyBool m_stop_on_crash = eLazyBoolCalculate;
0200 LazyBool m_echo_commands = eLazyBoolCalculate;
0201 LazyBool m_echo_comment_commands = eLazyBoolCalculate;
0202 LazyBool m_print_results = eLazyBoolCalculate;
0203 LazyBool m_print_errors = eLazyBoolCalculate;
0204 LazyBool m_add_to_history = eLazyBoolCalculate;
0205 LazyBool m_auto_handle_events;
0206 LazyBool m_spawn_thread;
0207 LazyBool m_allow_repeats = eLazyBoolCalculate;
0208
0209 private:
0210 static bool DefaultToYes(LazyBool flag) {
0211 switch (flag) {
0212 case eLazyBoolNo:
0213 return false;
0214 default:
0215 return true;
0216 }
0217 }
0218
0219 static bool DefaultToNo(LazyBool flag) {
0220 switch (flag) {
0221 case eLazyBoolYes:
0222 return true;
0223 default:
0224 return false;
0225 }
0226 }
0227 };
0228
0229 class CommandInterpreter : public Broadcaster,
0230 public Properties,
0231 public IOHandlerDelegate {
0232 public:
0233 enum {
0234 eBroadcastBitThreadShouldExit = (1 << 0),
0235 eBroadcastBitResetPrompt = (1 << 1),
0236 eBroadcastBitQuitCommandReceived = (1 << 2),
0237 eBroadcastBitAsynchronousOutputData = (1 << 3),
0238 eBroadcastBitAsynchronousErrorData = (1 << 4)
0239 };
0240
0241
0242 enum ChildrenOmissionWarningStatus {
0243 eNoOmission = 0,
0244 eUnwarnedOmission = 1,
0245 eWarnedOmission = 2
0246 };
0247
0248 enum CommandTypes {
0249 eCommandTypesBuiltin = 0x0001,
0250 eCommandTypesUserDef = 0x0002,
0251 eCommandTypesUserMW = 0x0004,
0252 eCommandTypesAliases = 0x0008,
0253 eCommandTypesHidden = 0x0010,
0254 eCommandTypesAllThem = 0xFFFF
0255 };
0256
0257
0258
0259
0260
0261 static const char *g_no_argument;
0262 static const char *g_need_argument;
0263 static const char *g_argument;
0264
0265 CommandInterpreter(Debugger &debugger, bool synchronous_execution);
0266
0267 ~CommandInterpreter() override = default;
0268
0269
0270
0271 static llvm::StringRef GetStaticBroadcasterClass();
0272
0273 llvm::StringRef GetBroadcasterClass() const override {
0274 return GetStaticBroadcasterClass();
0275 }
0276
0277 void SourceInitFileCwd(CommandReturnObject &result);
0278 void SourceInitFileHome(CommandReturnObject &result, bool is_repl);
0279 void SourceInitFileGlobal(CommandReturnObject &result);
0280
0281 bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp,
0282 bool can_replace);
0283
0284 Status AddUserCommand(llvm::StringRef name,
0285 const lldb::CommandObjectSP &cmd_sp, bool can_replace);
0286
0287 lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd,
0288 bool include_aliases = false) const;
0289
0290 CommandObject *GetCommandObject(llvm::StringRef cmd,
0291 StringList *matches = nullptr,
0292 StringList *descriptions = nullptr) const;
0293
0294 CommandObject *GetUserCommandObject(llvm::StringRef cmd,
0295 StringList *matches = nullptr,
0296 StringList *descriptions = nullptr) const;
0297
0298 CommandObject *
0299 GetAliasCommandObject(llvm::StringRef cmd, StringList *matches = nullptr,
0300 StringList *descriptions = nullptr) const;
0301
0302
0303 bool CommandExists(llvm::StringRef cmd) const;
0304
0305
0306 bool AliasExists(llvm::StringRef cmd) const;
0307
0308
0309 bool UserCommandExists(llvm::StringRef cmd) const;
0310
0311
0312
0313 bool UserMultiwordCommandExists(llvm::StringRef cmd) const;
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 CommandObjectMultiword *VerifyUserMultiwordCmdPath(Args &path,
0338 bool leaf_is_command,
0339 Status &result);
0340
0341 CommandAlias *AddAlias(llvm::StringRef alias_name,
0342 lldb::CommandObjectSP &command_obj_sp,
0343 llvm::StringRef args_string = llvm::StringRef());
0344
0345
0346
0347 bool RemoveCommand(llvm::StringRef cmd, bool force = false);
0348
0349 bool RemoveAlias(llvm::StringRef alias_name);
0350
0351 bool GetAliasFullName(llvm::StringRef cmd, std::string &full_name) const;
0352
0353 bool RemoveUserMultiword(llvm::StringRef multiword_name);
0354
0355
0356 void RemoveAllUserMultiword() { m_user_mw_dict.clear(); }
0357
0358 bool RemoveUser(llvm::StringRef alias_name);
0359
0360 void RemoveAllUser() { m_user_dict.clear(); }
0361
0362 const CommandAlias *GetAlias(llvm::StringRef alias_name) const;
0363
0364 CommandObject *BuildAliasResult(llvm::StringRef alias_name,
0365 std::string &raw_input_string,
0366 std::string &alias_result,
0367 CommandReturnObject &result);
0368
0369 bool HandleCommand(const char *command_line, LazyBool add_to_history,
0370 const ExecutionContext &override_context,
0371 CommandReturnObject &result);
0372
0373 bool HandleCommand(const char *command_line, LazyBool add_to_history,
0374 CommandReturnObject &result,
0375 bool force_repeat_command = false);
0376
0377 bool InterruptCommand();
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 void HandleCommands(const StringList &commands,
0395 const ExecutionContext &context,
0396 const CommandInterpreterRunOptions &options,
0397 CommandReturnObject &result);
0398
0399 void HandleCommands(const StringList &commands,
0400 const CommandInterpreterRunOptions &options,
0401 CommandReturnObject &result);
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context,
0419 const CommandInterpreterRunOptions &options,
0420 CommandReturnObject &result);
0421
0422 void HandleCommandsFromFile(FileSpec &file,
0423 const CommandInterpreterRunOptions &options,
0424 CommandReturnObject &result);
0425
0426 CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line);
0427
0428
0429
0430 std::optional<std::string> GetAutoSuggestionForCommand(llvm::StringRef line);
0431
0432
0433 void HandleCompletion(CompletionRequest &request);
0434
0435
0436
0437 void HandleCompletionMatches(CompletionRequest &request);
0438
0439 int GetCommandNamesMatchingPartialString(const char *cmd_cstr,
0440 bool include_aliases,
0441 StringList &matches,
0442 StringList &descriptions);
0443
0444 void GetHelp(CommandReturnObject &result,
0445 uint32_t types = eCommandTypesAllThem);
0446
0447 void GetAliasHelp(const char *alias_name, StreamString &help_string);
0448
0449 void OutputFormattedHelpText(Stream &strm, llvm::StringRef prefix,
0450 llvm::StringRef help_text);
0451
0452 void OutputFormattedHelpText(Stream &stream, llvm::StringRef command_word,
0453 llvm::StringRef separator,
0454 llvm::StringRef help_text, size_t max_word_len);
0455
0456
0457
0458
0459
0460
0461
0462 void OutputHelpText(Stream &stream, llvm::StringRef command_word,
0463 llvm::StringRef separator, llvm::StringRef help_text,
0464 uint32_t max_word_len);
0465
0466 Debugger &GetDebugger() { return m_debugger; }
0467
0468 ExecutionContext GetExecutionContext() const;
0469
0470 lldb::PlatformSP GetPlatform(bool prefer_target_platform);
0471
0472 const char *ProcessEmbeddedScriptCommands(const char *arg);
0473
0474 void UpdatePrompt(llvm::StringRef prompt);
0475
0476 bool Confirm(llvm::StringRef message, bool default_answer);
0477
0478 void LoadCommandDictionary();
0479
0480 void Initialize();
0481
0482 void Clear();
0483
0484 bool HasCommands() const;
0485
0486 bool HasAliases() const;
0487
0488 bool HasUserCommands() const;
0489
0490 bool HasUserMultiwordCommands() const;
0491
0492 bool HasAliasOptions() const;
0493
0494 void BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
0495 const char *alias_name, Args &cmd_args,
0496 std::string &raw_input_string,
0497 CommandReturnObject &result);
0498
0499
0500 int GetOptionArgumentPosition(const char *in_string);
0501
0502 void SkipLLDBInitFiles(bool skip_lldbinit_files) {
0503 m_skip_lldbinit_files = skip_lldbinit_files;
0504 }
0505
0506 void SkipAppInitFiles(bool skip_app_init_files) {
0507 m_skip_app_init_files = skip_app_init_files;
0508 }
0509
0510 bool GetSynchronous();
0511
0512 void FindCommandsForApropos(llvm::StringRef word, StringList &commands_found,
0513 StringList &commands_help,
0514 bool search_builtin_commands,
0515 bool search_user_commands,
0516 bool search_alias_commands,
0517 bool search_user_mw_commands);
0518
0519 bool GetBatchCommandMode() { return m_batch_command_mode; }
0520
0521 bool SetBatchCommandMode(bool value) {
0522 const bool old_value = m_batch_command_mode;
0523 m_batch_command_mode = value;
0524 return old_value;
0525 }
0526
0527 void ChildrenTruncated() {
0528 if (m_truncation_warning == eNoOmission)
0529 m_truncation_warning = eUnwarnedOmission;
0530 }
0531
0532 void SetReachedMaximumDepth() {
0533 if (m_max_depth_warning == eNoOmission)
0534 m_max_depth_warning = eUnwarnedOmission;
0535 }
0536
0537 void PrintWarningsIfNecessary(Stream &s, const std::string &cmd_name) {
0538 if (m_truncation_warning == eUnwarnedOmission) {
0539 s.Printf("*** Some of the displayed variables have more members than the "
0540 "debugger will show by default. To show all of them, you can "
0541 "either use the --show-all-children option to %s or raise the "
0542 "limit by changing the target.max-children-count setting.\n",
0543 cmd_name.c_str());
0544 m_truncation_warning = eWarnedOmission;
0545 }
0546
0547 if (m_max_depth_warning == eUnwarnedOmission) {
0548 s.Printf("*** Some of the displayed variables have a greater depth of "
0549 "members than the debugger will show by default. To increase "
0550 "the limit, use the --depth option to %s, or raise the limit by "
0551 "changing the target.max-children-depth setting.\n",
0552 cmd_name.c_str());
0553 m_max_depth_warning = eWarnedOmission;
0554 }
0555 }
0556
0557 CommandHistory &GetCommandHistory() { return m_command_history; }
0558
0559 bool IsActive();
0560
0561 CommandInterpreterRunResult
0562 RunCommandInterpreter(CommandInterpreterRunOptions &options);
0563
0564 void GetLLDBCommandsFromIOHandler(const char *prompt,
0565 IOHandlerDelegate &delegate,
0566 void *baton = nullptr);
0567
0568 void GetPythonCommandsFromIOHandler(const char *prompt,
0569 IOHandlerDelegate &delegate,
0570 void *baton = nullptr);
0571
0572 const char *GetCommandPrefix();
0573
0574
0575 bool GetExpandRegexAliases() const;
0576
0577 bool GetPromptOnQuit() const;
0578 void SetPromptOnQuit(bool enable);
0579
0580 bool GetSaveTranscript() const;
0581 void SetSaveTranscript(bool enable);
0582
0583 bool GetSaveSessionOnQuit() const;
0584 void SetSaveSessionOnQuit(bool enable);
0585
0586 bool GetOpenTranscriptInEditor() const;
0587 void SetOpenTranscriptInEditor(bool enable);
0588
0589 FileSpec GetSaveSessionDirectory() const;
0590 void SetSaveSessionDirectory(llvm::StringRef path);
0591
0592 bool GetEchoCommands() const;
0593 void SetEchoCommands(bool enable);
0594
0595 bool GetEchoCommentCommands() const;
0596 void SetEchoCommentCommands(bool enable);
0597
0598 bool GetRepeatPreviousCommand() const;
0599
0600 bool GetRequireCommandOverwrite() const;
0601
0602 const CommandObject::CommandMap &GetUserCommands() const {
0603 return m_user_dict;
0604 }
0605
0606 const CommandObject::CommandMap &GetUserMultiwordCommands() const {
0607 return m_user_mw_dict;
0608 }
0609
0610 const CommandObject::CommandMap &GetCommands() const {
0611 return m_command_dict;
0612 }
0613
0614 const CommandObject::CommandMap &GetAliases() const { return m_alias_dict; }
0615
0616
0617
0618 void AllowExitCodeOnQuit(bool allow);
0619
0620
0621
0622
0623
0624
0625
0626 [[nodiscard]] bool SetQuitExitCode(int exit_code);
0627
0628
0629
0630
0631
0632 int GetQuitExitCode(bool &exited) const;
0633
0634 void ResolveCommand(const char *command_line, CommandReturnObject &result);
0635
0636 bool GetStopCmdSourceOnError() const;
0637
0638 lldb::IOHandlerSP
0639 GetIOHandler(bool force_create = false,
0640 CommandInterpreterRunOptions *options = nullptr);
0641
0642 bool GetSpaceReplPrompts() const;
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653 bool SaveTranscript(CommandReturnObject &result,
0654 std::optional<std::string> output_file = std::nullopt);
0655
0656 FileSpec GetCurrentSourceDir();
0657
0658 bool IsInteractive();
0659
0660 bool IOHandlerInterrupt(IOHandler &io_handler) override;
0661
0662 Status PreprocessCommand(std::string &command);
0663 Status PreprocessToken(std::string &token);
0664
0665 void IncreaseCommandUsage(const CommandObject &cmd_obj) {
0666 ++m_command_usages[cmd_obj.GetCommandName()];
0667 }
0668
0669 llvm::json::Value GetStatistics();
0670 const StructuredData::Array &GetTranscript() const;
0671
0672 protected:
0673 friend class Debugger;
0674
0675
0676
0677 bool WasInterrupted() const;
0678
0679
0680 void IOHandlerInputComplete(IOHandler &io_handler,
0681 std::string &line) override;
0682
0683 llvm::StringRef IOHandlerGetControlSequence(char ch) override {
0684 static constexpr llvm::StringLiteral control_sequence("quit\n");
0685 if (ch == 'd')
0686 return control_sequence;
0687 return {};
0688 }
0689
0690 void GetProcessOutput();
0691
0692 bool DidProcessStopAbnormally() const;
0693
0694 void SetSynchronous(bool value);
0695
0696 lldb::CommandObjectSP GetCommandSP(llvm::StringRef cmd,
0697 bool include_aliases = true,
0698 bool exact = true,
0699 StringList *matches = nullptr,
0700 StringList *descriptions = nullptr) const;
0701
0702 private:
0703 void OverrideExecutionContext(const ExecutionContext &override_context);
0704
0705 void RestoreExecutionContext();
0706
0707 void SourceInitFile(FileSpec file, CommandReturnObject &result);
0708
0709
0710
0711
0712 CommandObject *ResolveCommandImpl(std::string &command_line,
0713 CommandReturnObject &result);
0714
0715 void FindCommandsForApropos(llvm::StringRef word, StringList &commands_found,
0716 StringList &commands_help,
0717 const CommandObject::CommandMap &command_map);
0718
0719
0720 void PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str,
0721 bool is_stdout);
0722
0723 bool EchoCommandNonInteractive(llvm::StringRef line,
0724 const Flags &io_handler_flags) const;
0725
0726
0727 enum class CommandHandlingState {
0728 eIdle,
0729 eInProgress,
0730 eInterrupted,
0731 };
0732
0733 std::atomic<CommandHandlingState> m_command_state{
0734 CommandHandlingState::eIdle};
0735
0736 int m_iohandler_nesting_level = 0;
0737
0738 void StartHandlingCommand();
0739 void FinishHandlingCommand();
0740
0741 Debugger &m_debugger;
0742
0743
0744
0745 std::stack<ExecutionContext> m_overriden_exe_contexts;
0746 bool m_synchronous_execution;
0747 bool m_skip_lldbinit_files;
0748 bool m_skip_app_init_files;
0749 CommandObject::CommandMap m_command_dict;
0750
0751
0752 CommandObject::CommandMap
0753 m_alias_dict;
0754 CommandObject::CommandMap m_user_dict;
0755 CommandObject::CommandMap
0756 m_user_mw_dict;
0757 CommandHistory m_command_history;
0758 std::string m_repeat_command;
0759
0760 lldb::IOHandlerSP m_command_io_handler_sp;
0761 char m_comment_char;
0762 bool m_batch_command_mode;
0763
0764
0765 ChildrenOmissionWarningStatus m_truncation_warning;
0766
0767
0768 ChildrenOmissionWarningStatus m_max_depth_warning;
0769
0770
0771
0772 uint32_t m_command_source_depth;
0773
0774
0775 std::vector<FileSpec> m_command_source_dirs;
0776 std::vector<uint32_t> m_command_source_flags;
0777 CommandInterpreterRunResult m_result;
0778
0779
0780
0781 std::optional<int> m_quit_exit_code;
0782
0783 bool m_allow_exit_code = false;
0784
0785
0786 typedef llvm::StringMap<uint64_t> CommandUsageMap;
0787 CommandUsageMap m_command_usages;
0788
0789
0790
0791 StreamString m_transcript_stream;
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806 StructuredData::Array m_transcript;
0807 };
0808
0809 }
0810
0811 #endif