File indexing completed on 2026-05-10 08:42:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_INTERPRETER_COMMANDOBJECT_H
0010 #define LLDB_INTERPRETER_COMMANDOBJECT_H
0011
0012 #include <map>
0013 #include <memory>
0014 #include <optional>
0015 #include <string>
0016 #include <vector>
0017
0018 #include "lldb/Utility/Flags.h"
0019
0020 #include "lldb/Interpreter/CommandCompletions.h"
0021 #include "lldb/Interpreter/Options.h"
0022 #include "lldb/Target/ExecutionContext.h"
0023 #include "lldb/Utility/Args.h"
0024 #include "lldb/Utility/CompletionRequest.h"
0025 #include "lldb/Utility/StringList.h"
0026 #include "lldb/lldb-private.h"
0027
0028 namespace lldb_private {
0029
0030
0031
0032
0033
0034
0035
0036 template <typename ValueType>
0037 int AddNamesMatchingPartialString(
0038 const std::map<std::string, ValueType, std::less<>> &in_map,
0039 llvm::StringRef cmd_str, StringList &matches,
0040 StringList *descriptions = nullptr) {
0041 int number_added = 0;
0042
0043 const bool add_all = cmd_str.empty();
0044
0045 for (auto iter = in_map.begin(), end = in_map.end(); iter != end; iter++) {
0046 if (add_all || (iter->first.find(std::string(cmd_str), 0) == 0)) {
0047 ++number_added;
0048 matches.AppendString(iter->first.c_str());
0049 if (descriptions)
0050 descriptions->AppendString(iter->second->GetHelp());
0051 }
0052 }
0053
0054 return number_added;
0055 }
0056
0057 template <typename ValueType>
0058 size_t
0059 FindLongestCommandWord(std::map<std::string, ValueType, std::less<>> &dict) {
0060 auto end = dict.end();
0061 size_t max_len = 0;
0062
0063 for (auto pos = dict.begin(); pos != end; ++pos) {
0064 size_t len = pos->first.size();
0065 if (max_len < len)
0066 max_len = len;
0067 }
0068 return max_len;
0069 }
0070
0071 class CommandObject : public std::enable_shared_from_this<CommandObject> {
0072 public:
0073 typedef llvm::StringRef(ArgumentHelpCallbackFunction)();
0074
0075 struct ArgumentHelpCallback {
0076 ArgumentHelpCallbackFunction *help_callback;
0077 bool self_formatting;
0078
0079 llvm::StringRef operator()() const { return (*help_callback)(); }
0080
0081 explicit operator bool() const { return (help_callback != nullptr); }
0082 };
0083
0084
0085 struct ArgumentTableEntry {
0086 lldb::CommandArgumentType arg_type;
0087 const char *arg_name;
0088 lldb::CompletionType completion_type;
0089 OptionEnumValues enum_values;
0090 ArgumentHelpCallback help_function;
0091 const char *help_text;
0092 };
0093
0094
0095 struct CommandArgumentData {
0096 lldb::CommandArgumentType arg_type;
0097 ArgumentRepetitionType arg_repetition;
0098
0099
0100 uint32_t arg_opt_set_association;
0101
0102 CommandArgumentData(lldb::CommandArgumentType type = lldb::eArgTypeNone,
0103 ArgumentRepetitionType repetition = eArgRepeatPlain,
0104 uint32_t opt_set = LLDB_OPT_SET_ALL)
0105 : arg_type(type), arg_repetition(repetition),
0106 arg_opt_set_association(opt_set) {}
0107 };
0108
0109 typedef std::vector<CommandArgumentData>
0110 CommandArgumentEntry;
0111
0112 typedef std::map<std::string, lldb::CommandObjectSP, std::less<>> CommandMap;
0113
0114 CommandObject(CommandInterpreter &interpreter, llvm::StringRef name,
0115 llvm::StringRef help = "", llvm::StringRef syntax = "",
0116 uint32_t flags = 0);
0117
0118 virtual ~CommandObject() = default;
0119
0120 static const char *
0121 GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type);
0122
0123 static const char *
0124 GetArgumentDescriptionAsCString(const lldb::CommandArgumentType arg_type);
0125
0126 CommandInterpreter &GetCommandInterpreter() { return m_interpreter; }
0127 Debugger &GetDebugger();
0128
0129 virtual llvm::StringRef GetHelp();
0130
0131 virtual llvm::StringRef GetHelpLong();
0132
0133 virtual llvm::StringRef GetSyntax();
0134
0135 llvm::StringRef GetCommandName() const;
0136
0137 virtual void SetHelp(llvm::StringRef str);
0138
0139 virtual void SetHelpLong(llvm::StringRef str);
0140
0141 void SetSyntax(llvm::StringRef str);
0142
0143
0144
0145
0146 virtual bool IsRemovable() const { return false; }
0147
0148 virtual bool IsMultiwordObject() { return false; }
0149
0150 bool IsUserCommand() { return m_is_user_command; }
0151
0152 void SetIsUserCommand(bool is_user) { m_is_user_command = is_user; }
0153
0154 virtual CommandObjectMultiword *GetAsMultiwordCommand() { return nullptr; }
0155
0156 virtual bool IsAlias() { return false; }
0157
0158
0159
0160
0161 virtual bool IsDashDashCommand() { return false; }
0162
0163 virtual lldb::CommandObjectSP GetSubcommandSP(llvm::StringRef sub_cmd,
0164 StringList *matches = nullptr) {
0165 return lldb::CommandObjectSP();
0166 }
0167
0168 virtual lldb::CommandObjectSP GetSubcommandSPExact(llvm::StringRef sub_cmd) {
0169 return lldb::CommandObjectSP();
0170 }
0171
0172 virtual CommandObject *GetSubcommandObject(llvm::StringRef sub_cmd,
0173 StringList *matches = nullptr) {
0174 return nullptr;
0175 }
0176
0177 void FormatLongHelpText(Stream &output_strm, llvm::StringRef long_help);
0178
0179 void GenerateHelpText(CommandReturnObject &result);
0180
0181 virtual void GenerateHelpText(Stream &result);
0182
0183
0184
0185
0186 virtual bool LoadSubCommand(llvm::StringRef cmd_name,
0187 const lldb::CommandObjectSP &command_obj) {
0188 return false;
0189 }
0190
0191 virtual llvm::Error LoadUserSubcommand(llvm::StringRef cmd_name,
0192 const lldb::CommandObjectSP &command_obj,
0193 bool can_replace) {
0194 return llvm::createStringError(llvm::inconvertibleErrorCode(),
0195 "can only add commands to container commands");
0196 }
0197
0198 virtual bool WantsRawCommandString() = 0;
0199
0200
0201
0202
0203 virtual bool WantsCompletion() { return !WantsRawCommandString(); }
0204
0205 virtual Options *GetOptions();
0206
0207 static lldb::CommandArgumentType LookupArgumentName(llvm::StringRef arg_name);
0208
0209 static const ArgumentTableEntry *
0210 FindArgumentDataByType(lldb::CommandArgumentType arg_type);
0211
0212
0213
0214 void AddSimpleArgumentList(
0215 lldb::CommandArgumentType arg_type,
0216 ArgumentRepetitionType repetition_type = eArgRepeatPlain);
0217
0218
0219
0220
0221
0222
0223 enum IDType { eBreakpointArgs = 0, eWatchpointArgs = 1 };
0224 void AddIDsArgumentData(IDType type);
0225
0226 int GetNumArgumentEntries();
0227
0228 CommandArgumentEntry *GetArgumentEntryAtIndex(int idx);
0229
0230 static void GetArgumentHelp(Stream &str, lldb::CommandArgumentType arg_type,
0231 CommandInterpreter &interpreter);
0232
0233 static const char *GetArgumentName(lldb::CommandArgumentType arg_type);
0234
0235
0236
0237
0238
0239
0240 void GetFormattedCommandArguments(Stream &str,
0241 uint32_t opt_set_mask = LLDB_OPT_SET_ALL);
0242
0243 static bool IsPairType(ArgumentRepetitionType arg_repeat_type);
0244
0245 static std::optional<ArgumentRepetitionType>
0246 ArgRepetitionFromString(llvm::StringRef string);
0247
0248 bool ParseOptions(Args &args, CommandReturnObject &result);
0249
0250 void SetCommandName(llvm::StringRef name);
0251
0252
0253
0254
0255
0256
0257
0258
0259 virtual void HandleCompletion(CompletionRequest &request);
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 virtual void
0276 HandleArgumentCompletion(CompletionRequest &request,
0277 OptionElementVector &opt_element_vector);
0278
0279 bool HelpTextContainsWord(llvm::StringRef search_word,
0280 bool search_short_help = true,
0281 bool search_long_help = true,
0282 bool search_syntax = true,
0283 bool search_options = true);
0284
0285
0286
0287
0288
0289 Flags &GetFlags() { return m_flags; }
0290
0291
0292
0293
0294
0295 const Flags &GetFlags() const { return m_flags; }
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311 virtual std::optional<std::string>
0312 GetRepeatCommand(Args ¤t_command_args, uint32_t index) {
0313 return std::nullopt;
0314 }
0315
0316 bool HasOverrideCallback() const {
0317 return m_command_override_callback ||
0318 m_deprecated_command_override_callback;
0319 }
0320
0321 void SetOverrideCallback(lldb::CommandOverrideCallback callback,
0322 void *baton) {
0323 m_deprecated_command_override_callback = callback;
0324 m_command_override_baton = baton;
0325 }
0326
0327 void
0328 SetOverrideCallback(lldb_private::CommandOverrideCallbackWithResult callback,
0329 void *baton) {
0330 m_command_override_callback = callback;
0331 m_command_override_baton = baton;
0332 }
0333
0334 bool InvokeOverrideCallback(const char **argv, CommandReturnObject &result) {
0335 if (m_command_override_callback)
0336 return m_command_override_callback(m_command_override_baton, argv,
0337 result);
0338 else if (m_deprecated_command_override_callback)
0339 return m_deprecated_command_override_callback(m_command_override_baton,
0340 argv);
0341 else
0342 return false;
0343 }
0344
0345
0346
0347 void SetOriginalCommandString(std::string s) { m_original_command = s; }
0348
0349
0350
0351
0352 virtual void Execute(const char *args_string,
0353 CommandReturnObject &result) = 0;
0354
0355 protected:
0356 bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result,
0357 OptionGroupOptions &group_options,
0358 ExecutionContext &exe_ctx);
0359
0360 virtual const char *GetInvalidTargetDescription() {
0361 return "invalid target, create a target using the 'target create' command";
0362 }
0363
0364 virtual const char *GetInvalidProcessDescription() {
0365 return "Command requires a current process.";
0366 }
0367
0368 virtual const char *GetInvalidThreadDescription() {
0369 return "Command requires a process which is currently stopped.";
0370 }
0371
0372 virtual const char *GetInvalidFrameDescription() {
0373 return "Command requires a process, which is currently stopped.";
0374 }
0375
0376 virtual const char *GetInvalidRegContextDescription() {
0377 return "invalid frame, no registers, command requires a process which is "
0378 "currently stopped.";
0379 }
0380
0381 Target &GetDummyTarget();
0382
0383
0384
0385
0386
0387 Target &GetTarget();
0388
0389
0390
0391
0392
0393
0394 Thread *GetDefaultThread();
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 bool CheckRequirements(CommandReturnObject &result);
0406
0407 void Cleanup();
0408
0409 CommandInterpreter &m_interpreter;
0410 ExecutionContext m_exe_ctx;
0411 std::unique_lock<std::recursive_mutex> m_api_locker;
0412 std::string m_cmd_name;
0413 std::string m_cmd_help_short;
0414 std::string m_cmd_help_long;
0415 std::string m_cmd_syntax;
0416 std::string m_original_command;
0417 Flags m_flags;
0418 std::vector<CommandArgumentEntry> m_arguments;
0419 lldb::CommandOverrideCallback m_deprecated_command_override_callback;
0420 lldb_private::CommandOverrideCallbackWithResult m_command_override_callback;
0421 void *m_command_override_baton;
0422 bool m_is_user_command = false;
0423 };
0424
0425 class CommandObjectParsed : public CommandObject {
0426 public:
0427 CommandObjectParsed(CommandInterpreter &interpreter, const char *name,
0428 const char *help = nullptr, const char *syntax = nullptr,
0429 uint32_t flags = 0)
0430 : CommandObject(interpreter, name, help, syntax, flags) {}
0431
0432 ~CommandObjectParsed() override = default;
0433
0434 void Execute(const char *args_string, CommandReturnObject &result) override;
0435
0436 protected:
0437 virtual void DoExecute(Args &command, CommandReturnObject &result) = 0;
0438
0439 bool WantsRawCommandString() override { return false; }
0440 };
0441
0442 class CommandObjectRaw : public CommandObject {
0443 public:
0444 CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name,
0445 llvm::StringRef help = "", llvm::StringRef syntax = "",
0446 uint32_t flags = 0)
0447 : CommandObject(interpreter, name, help, syntax, flags) {}
0448
0449 ~CommandObjectRaw() override = default;
0450
0451 void Execute(const char *args_string, CommandReturnObject &result) override;
0452
0453 protected:
0454 virtual void DoExecute(llvm::StringRef command,
0455 CommandReturnObject &result) = 0;
0456
0457 bool WantsRawCommandString() override { return true; }
0458 };
0459
0460 }
0461
0462 #endif