CommandObject.h revision 360784
1//===-- CommandObject.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 liblldb_CommandObject_h_
10#define liblldb_CommandObject_h_
11
12#include <map>
13#include <string>
14#include <vector>
15
16#include "lldb/Utility/Flags.h"
17
18#include "lldb/Interpreter/CommandCompletions.h"
19#include "lldb/Interpreter/Options.h"
20#include "lldb/Target/ExecutionContext.h"
21#include "lldb/Utility/Args.h"
22#include "lldb/Utility/CompletionRequest.h"
23#include "lldb/Utility/StringList.h"
24#include "lldb/lldb-private.h"
25
26namespace lldb_private {
27
28// This function really deals with CommandObjectLists, but we didn't make a
29// CommandObjectList class, so I'm sticking it here.  But we really should have
30// such a class.  Anyway, it looks up the commands in the map that match the
31// partial string cmd_str, inserts the matches into matches, and returns the
32// number added.
33
34template <typename ValueType>
35int AddNamesMatchingPartialString(
36    const std::map<std::string, ValueType> &in_map, llvm::StringRef cmd_str,
37    StringList &matches, StringList *descriptions = nullptr) {
38  int number_added = 0;
39
40  const bool add_all = cmd_str.empty();
41
42  for (auto iter = in_map.begin(), end = in_map.end(); iter != end; iter++) {
43    if (add_all || (iter->first.find(cmd_str, 0) == 0)) {
44      ++number_added;
45      matches.AppendString(iter->first.c_str());
46      if (descriptions)
47        descriptions->AppendString(iter->second->GetHelp());
48    }
49  }
50
51  return number_added;
52}
53
54template <typename ValueType>
55size_t FindLongestCommandWord(std::map<std::string, ValueType> &dict) {
56  auto end = dict.end();
57  size_t max_len = 0;
58
59  for (auto pos = dict.begin(); pos != end; ++pos) {
60    size_t len = pos->first.size();
61    if (max_len < len)
62      max_len = len;
63  }
64  return max_len;
65}
66
67class CommandObject {
68public:
69  typedef llvm::StringRef(ArgumentHelpCallbackFunction)();
70
71  struct ArgumentHelpCallback {
72    ArgumentHelpCallbackFunction *help_callback;
73    bool self_formatting;
74
75    llvm::StringRef operator()() const { return (*help_callback)(); }
76
77    explicit operator bool() const { return (help_callback != nullptr); }
78  };
79
80  struct ArgumentTableEntry // Entries in the main argument information table
81  {
82    lldb::CommandArgumentType arg_type;
83    const char *arg_name;
84    CommandCompletions::CommonCompletionTypes completion_type;
85    ArgumentHelpCallback help_function;
86    const char *help_text;
87  };
88
89  struct CommandArgumentData // Used to build individual command argument lists
90  {
91    lldb::CommandArgumentType arg_type;
92    ArgumentRepetitionType arg_repetition;
93    uint32_t arg_opt_set_association; // This arg might be associated only with
94                                      // some particular option set(s).
95    CommandArgumentData()
96        : arg_type(lldb::eArgTypeNone), arg_repetition(eArgRepeatPlain),
97          arg_opt_set_association(LLDB_OPT_SET_ALL) // By default, the arg
98                                                    // associates to all option
99                                                    // sets.
100    {}
101  };
102
103  typedef std::vector<CommandArgumentData>
104      CommandArgumentEntry; // Used to build individual command argument lists
105
106  static ArgumentTableEntry g_arguments_data
107      [lldb::eArgTypeLastArg]; // Main argument information table
108
109  typedef std::map<std::string, lldb::CommandObjectSP> CommandMap;
110
111  CommandObject(CommandInterpreter &interpreter, llvm::StringRef name,
112    llvm::StringRef help = "", llvm::StringRef syntax = "",
113                uint32_t flags = 0);
114
115  virtual ~CommandObject();
116
117  static const char *
118  GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type);
119
120  static const char *
121  GetArgumentDescriptionAsCString(const lldb::CommandArgumentType arg_type);
122
123  CommandInterpreter &GetCommandInterpreter() { return m_interpreter; }
124  Debugger &GetDebugger();
125
126  virtual llvm::StringRef GetHelp();
127
128  virtual llvm::StringRef GetHelpLong();
129
130  virtual llvm::StringRef GetSyntax();
131
132  llvm::StringRef GetCommandName() const;
133
134  virtual void SetHelp(llvm::StringRef str);
135
136  virtual void SetHelpLong(llvm::StringRef str);
137
138  void SetSyntax(llvm::StringRef str);
139
140  // override this to return true if you want to enable the user to delete the
141  // Command object from the Command dictionary (aliases have their own
142  // deletion scheme, so they do not need to care about this)
143  virtual bool IsRemovable() const { return false; }
144
145  virtual bool IsMultiwordObject() { return false; }
146
147  virtual CommandObjectMultiword *GetAsMultiwordCommand() { return nullptr; }
148
149  virtual bool IsAlias() { return false; }
150
151  // override this to return true if your command is somehow a "dash-dash" form
152  // of some other command (e.g. po is expr -O --); this is a powerful hint to
153  // the help system that one cannot pass options to this command
154  virtual bool IsDashDashCommand() { return false; }
155
156  virtual lldb::CommandObjectSP GetSubcommandSP(llvm::StringRef sub_cmd,
157                                                StringList *matches = nullptr) {
158    return lldb::CommandObjectSP();
159  }
160
161  virtual CommandObject *GetSubcommandObject(llvm::StringRef sub_cmd,
162                                             StringList *matches = nullptr) {
163    return nullptr;
164  }
165
166  virtual void AproposAllSubCommands(llvm::StringRef prefix,
167                                     llvm::StringRef search_word,
168                                     StringList &commands_found,
169                                     StringList &commands_help) {}
170
171  void FormatLongHelpText(Stream &output_strm, llvm::StringRef long_help);
172
173  void GenerateHelpText(CommandReturnObject &result);
174
175  virtual void GenerateHelpText(Stream &result);
176
177  // this is needed in order to allow the SBCommand class to transparently try
178  // and load subcommands - it will fail on anything but a multiword command,
179  // but it avoids us doing type checkings and casts
180  virtual bool LoadSubCommand(llvm::StringRef cmd_name,
181                              const lldb::CommandObjectSP &command_obj) {
182    return false;
183  }
184
185  virtual bool WantsRawCommandString() = 0;
186
187  // By default, WantsCompletion = !WantsRawCommandString. Subclasses who want
188  // raw command string but desire, for example, argument completion should
189  // override this method to return true.
190  virtual bool WantsCompletion() { return !WantsRawCommandString(); }
191
192  virtual Options *GetOptions();
193
194  static const ArgumentTableEntry *GetArgumentTable();
195
196  static lldb::CommandArgumentType LookupArgumentName(llvm::StringRef arg_name);
197
198  static const ArgumentTableEntry *
199  FindArgumentDataByType(lldb::CommandArgumentType arg_type);
200
201  int GetNumArgumentEntries();
202
203  CommandArgumentEntry *GetArgumentEntryAtIndex(int idx);
204
205  static void GetArgumentHelp(Stream &str, lldb::CommandArgumentType arg_type,
206                              CommandInterpreter &interpreter);
207
208  static const char *GetArgumentName(lldb::CommandArgumentType arg_type);
209
210  // Generates a nicely formatted command args string for help command output.
211  // By default, all possible args are taken into account, for example, '<expr
212  // | variable-name>'.  This can be refined by passing a second arg specifying
213  // which option set(s) we are interested, which could then, for example,
214  // produce either '<expr>' or '<variable-name>'.
215  void GetFormattedCommandArguments(Stream &str,
216                                    uint32_t opt_set_mask = LLDB_OPT_SET_ALL);
217
218  bool IsPairType(ArgumentRepetitionType arg_repeat_type);
219
220  bool ParseOptions(Args &args, CommandReturnObject &result);
221
222  void SetCommandName(llvm::StringRef name);
223
224  /// This default version handles calling option argument completions and then
225  /// calls HandleArgumentCompletion if the cursor is on an argument, not an
226  /// option. Don't override this method, override HandleArgumentCompletion
227  /// instead unless you have special reasons.
228  ///
229  /// \param[in,out] request
230  ///    The completion request that needs to be answered.
231  virtual void HandleCompletion(CompletionRequest &request);
232
233  /// The input array contains a parsed version of the line.
234  ///
235  /// We've constructed the map of options and their arguments as well if that
236  /// is helpful for the completion.
237  ///
238  /// \param[in,out] request
239  ///    The completion request that needs to be answered.
240  virtual void
241  HandleArgumentCompletion(CompletionRequest &request,
242                           OptionElementVector &opt_element_vector) {}
243
244  bool HelpTextContainsWord(llvm::StringRef search_word,
245                            bool search_short_help = true,
246                            bool search_long_help = true,
247                            bool search_syntax = true,
248                            bool search_options = true);
249
250  /// The flags accessor.
251  ///
252  /// \return
253  ///     A reference to the Flags member variable.
254  Flags &GetFlags() { return m_flags; }
255
256  /// The flags const accessor.
257  ///
258  /// \return
259  ///     A const reference to the Flags member variable.
260  const Flags &GetFlags() const { return m_flags; }
261
262  /// Get the command that appropriate for a "repeat" of the current command.
263  ///
264  /// \param[in] current_command_args
265  ///    The command arguments.
266  ///
267  /// \return
268  ///     nullptr if there is no special repeat command - it will use the
269  ///     current command line.
270  ///     Otherwise a pointer to the command to be repeated.
271  ///     If the returned string is the empty string, the command won't be
272  ///     repeated.
273  virtual const char *GetRepeatCommand(Args &current_command_args,
274                                       uint32_t index) {
275    return nullptr;
276  }
277
278  bool HasOverrideCallback() const {
279    return m_command_override_callback ||
280           m_deprecated_command_override_callback;
281  }
282
283  void SetOverrideCallback(lldb::CommandOverrideCallback callback,
284                           void *baton) {
285    m_deprecated_command_override_callback = callback;
286    m_command_override_baton = baton;
287  }
288
289  void SetOverrideCallback(lldb::CommandOverrideCallbackWithResult callback,
290                           void *baton) {
291    m_command_override_callback = callback;
292    m_command_override_baton = baton;
293  }
294
295  bool InvokeOverrideCallback(const char **argv, CommandReturnObject &result) {
296    if (m_command_override_callback)
297      return m_command_override_callback(m_command_override_baton, argv,
298                                         result);
299    else if (m_deprecated_command_override_callback)
300      return m_deprecated_command_override_callback(m_command_override_baton,
301                                                    argv);
302    else
303      return false;
304  }
305
306  virtual bool Execute(const char *args_string,
307                       CommandReturnObject &result) = 0;
308
309protected:
310  bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result,
311                             OptionGroupOptions &group_options,
312                             ExecutionContext &exe_ctx);
313
314  virtual const char *GetInvalidTargetDescription() {
315    return "invalid target, create a target using the 'target create' command";
316  }
317
318  virtual const char *GetInvalidProcessDescription() {
319    return "invalid process";
320  }
321
322  virtual const char *GetInvalidThreadDescription() { return "invalid thread"; }
323
324  virtual const char *GetInvalidFrameDescription() { return "invalid frame"; }
325
326  virtual const char *GetInvalidRegContextDescription() {
327    return "invalid frame, no registers";
328  }
329
330  // This is for use in the command interpreter, when you either want the
331  // selected target, or if no target is present you want to prime the dummy
332  // target with entities that will be copied over to new targets.
333  Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
334  Target &GetSelectedTarget();
335  Target &GetDummyTarget();
336
337  // If a command needs to use the "current" thread, use this call. Command
338  // objects will have an ExecutionContext to use, and that may or may not have
339  // a thread in it.  If it does, you should use that by default, if not, then
340  // use the ExecutionContext's target's selected thread, etc... This call
341  // insulates you from the details of this calculation.
342  Thread *GetDefaultThread();
343
344  /// Check the command to make sure anything required by this
345  /// command is available.
346  ///
347  /// \param[out] result
348  ///     A command result object, if it is not okay to run the command
349  ///     this will be filled in with a suitable error.
350  ///
351  /// \return
352  ///     \b true if it is okay to run this command, \b false otherwise.
353  bool CheckRequirements(CommandReturnObject &result);
354
355  void Cleanup();
356
357  CommandInterpreter &m_interpreter;
358  ExecutionContext m_exe_ctx;
359  std::unique_lock<std::recursive_mutex> m_api_locker;
360  std::string m_cmd_name;
361  std::string m_cmd_help_short;
362  std::string m_cmd_help_long;
363  std::string m_cmd_syntax;
364  Flags m_flags;
365  std::vector<CommandArgumentEntry> m_arguments;
366  lldb::CommandOverrideCallback m_deprecated_command_override_callback;
367  lldb::CommandOverrideCallbackWithResult m_command_override_callback;
368  void *m_command_override_baton;
369
370  // Helper function to populate IDs or ID ranges as the command argument data
371  // to the specified command argument entry.
372  static void AddIDsArgumentData(CommandArgumentEntry &arg,
373                                 lldb::CommandArgumentType ID,
374                                 lldb::CommandArgumentType IDRange);
375};
376
377class CommandObjectParsed : public CommandObject {
378public:
379  CommandObjectParsed(CommandInterpreter &interpreter, const char *name,
380                      const char *help = nullptr, const char *syntax = nullptr,
381                      uint32_t flags = 0)
382      : CommandObject(interpreter, name, help, syntax, flags) {}
383
384  ~CommandObjectParsed() override = default;
385
386  bool Execute(const char *args_string, CommandReturnObject &result) override;
387
388protected:
389  virtual bool DoExecute(Args &command, CommandReturnObject &result) = 0;
390
391  bool WantsRawCommandString() override { return false; }
392};
393
394class CommandObjectRaw : public CommandObject {
395public:
396  CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name,
397    llvm::StringRef help = "", llvm::StringRef syntax = "",
398                   uint32_t flags = 0)
399      : CommandObject(interpreter, name, help, syntax, flags) {}
400
401  ~CommandObjectRaw() override = default;
402
403  bool Execute(const char *args_string, CommandReturnObject &result) override;
404
405protected:
406  virtual bool DoExecute(llvm::StringRef command,
407                         CommandReturnObject &result) = 0;
408
409  bool WantsRawCommandString() override { return true; }
410};
411
412} // namespace lldb_private
413
414#endif // liblldb_CommandObject_h_
415