1cfca06d7SDimitry Andric //===-- CommandObjectMultiword.cpp ----------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f3fbd1c0SDimitry Andric #include "lldb/Interpreter/CommandObjectMultiword.h"
10f034231aSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
11f034231aSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
1214f1b3e8SDimitry Andric #include "lldb/Interpreter/Options.h"
13e3b55780SDimitry Andric #include <optional>
14f034231aSEd Maste
15f034231aSEd Maste using namespace lldb;
16f034231aSEd Maste using namespace lldb_private;
17f034231aSEd Maste
18f034231aSEd Maste // CommandObjectMultiword
19f034231aSEd Maste
CommandObjectMultiword(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)20f3fbd1c0SDimitry Andric CommandObjectMultiword::CommandObjectMultiword(CommandInterpreter &interpreter,
21f034231aSEd Maste const char *name,
22f034231aSEd Maste const char *help,
23f034231aSEd Maste const char *syntax,
2414f1b3e8SDimitry Andric uint32_t flags)
2514f1b3e8SDimitry Andric : CommandObject(interpreter, name, help, syntax, flags),
2614f1b3e8SDimitry Andric m_can_be_removed(false) {}
27f034231aSEd Maste
28f3fbd1c0SDimitry Andric CommandObjectMultiword::~CommandObjectMultiword() = default;
29f034231aSEd Maste
30c0981da4SDimitry Andric CommandObjectSP
GetSubcommandSPExact(llvm::StringRef sub_cmd)31c0981da4SDimitry Andric CommandObjectMultiword::GetSubcommandSPExact(llvm::StringRef sub_cmd) {
32c0981da4SDimitry Andric if (m_subcommand_dict.empty())
33c0981da4SDimitry Andric return {};
34c0981da4SDimitry Andric
35c0981da4SDimitry Andric auto pos = m_subcommand_dict.find(std::string(sub_cmd));
36c0981da4SDimitry Andric if (pos == m_subcommand_dict.end())
37c0981da4SDimitry Andric return {};
38c0981da4SDimitry Andric
39c0981da4SDimitry Andric return pos->second;
40c0981da4SDimitry Andric }
41c0981da4SDimitry Andric
GetSubcommandSP(llvm::StringRef sub_cmd,StringList * matches)4214f1b3e8SDimitry Andric CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd,
4314f1b3e8SDimitry Andric StringList *matches) {
44c0981da4SDimitry Andric if (m_subcommand_dict.empty())
45c0981da4SDimitry Andric return {};
46f034231aSEd Maste
47c0981da4SDimitry Andric CommandObjectSP return_cmd_sp = GetSubcommandSPExact(sub_cmd);
48c0981da4SDimitry Andric if (return_cmd_sp) {
49f034231aSEd Maste if (matches)
50f034231aSEd Maste matches->AppendString(sub_cmd);
51c0981da4SDimitry Andric return return_cmd_sp;
52c0981da4SDimitry Andric }
53c0981da4SDimitry Andric
54c0981da4SDimitry Andric CommandObject::CommandMap::iterator pos;
55c0981da4SDimitry Andric
56f034231aSEd Maste StringList local_matches;
57f3fbd1c0SDimitry Andric if (matches == nullptr)
58f034231aSEd Maste matches = &local_matches;
5914f1b3e8SDimitry Andric int num_matches =
6014f1b3e8SDimitry Andric AddNamesMatchingPartialString(m_subcommand_dict, sub_cmd, *matches);
61f034231aSEd Maste
6214f1b3e8SDimitry Andric if (num_matches == 1) {
6314f1b3e8SDimitry Andric // Cleaner, but slightly less efficient would be to call back into this
64f73363f1SDimitry Andric // function, since I now know I have an exact match...
65f034231aSEd Maste
66f034231aSEd Maste sub_cmd = matches->GetStringAtIndex(0);
67cfca06d7SDimitry Andric pos = m_subcommand_dict.find(std::string(sub_cmd));
68f034231aSEd Maste if (pos != m_subcommand_dict.end())
69f034231aSEd Maste return_cmd_sp = pos->second;
70f034231aSEd Maste }
71c0981da4SDimitry Andric
72f034231aSEd Maste return return_cmd_sp;
73f034231aSEd Maste }
74f034231aSEd Maste
75f034231aSEd Maste CommandObject *
GetSubcommandObject(llvm::StringRef sub_cmd,StringList * matches)7614f1b3e8SDimitry Andric CommandObjectMultiword::GetSubcommandObject(llvm::StringRef sub_cmd,
7714f1b3e8SDimitry Andric StringList *matches) {
78f034231aSEd Maste return GetSubcommandSP(sub_cmd, matches).get();
79f034231aSEd Maste }
80f034231aSEd Maste
LoadSubCommand(llvm::StringRef name,const CommandObjectSP & cmd_obj_sp)8114f1b3e8SDimitry Andric bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name,
82c0981da4SDimitry Andric const CommandObjectSP &cmd_obj_sp) {
83c0981da4SDimitry Andric if (cmd_obj_sp)
84c0981da4SDimitry Andric lldbassert((&GetCommandInterpreter() == &cmd_obj_sp->GetCommandInterpreter()) &&
8514f1b3e8SDimitry Andric "tried to add a CommandObject from a different interpreter");
86f3fbd1c0SDimitry Andric
87f034231aSEd Maste CommandMap::iterator pos;
88f034231aSEd Maste bool success = true;
89f034231aSEd Maste
90cfca06d7SDimitry Andric pos = m_subcommand_dict.find(std::string(name));
9114f1b3e8SDimitry Andric if (pos == m_subcommand_dict.end()) {
92c0981da4SDimitry Andric m_subcommand_dict[std::string(name)] = cmd_obj_sp;
9314f1b3e8SDimitry Andric } else
94f034231aSEd Maste success = false;
95f034231aSEd Maste
96f034231aSEd Maste return success;
97f034231aSEd Maste }
98f034231aSEd Maste
LoadUserSubcommand(llvm::StringRef name,const CommandObjectSP & cmd_obj_sp,bool can_replace)99c0981da4SDimitry Andric llvm::Error CommandObjectMultiword::LoadUserSubcommand(
100c0981da4SDimitry Andric llvm::StringRef name, const CommandObjectSP &cmd_obj_sp, bool can_replace) {
101c0981da4SDimitry Andric Status result;
102c0981da4SDimitry Andric if (cmd_obj_sp)
103c0981da4SDimitry Andric lldbassert((&GetCommandInterpreter() == &cmd_obj_sp->GetCommandInterpreter()) &&
104c0981da4SDimitry Andric "tried to add a CommandObject from a different interpreter");
105c0981da4SDimitry Andric if (!IsUserCommand()) {
106c0981da4SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
107c0981da4SDimitry Andric "can't add a user subcommand to a builtin container command.");
108c0981da4SDimitry Andric }
109c0981da4SDimitry Andric // Make sure this a user command if it isn't already:
110c0981da4SDimitry Andric cmd_obj_sp->SetIsUserCommand(true);
111c0981da4SDimitry Andric
112c0981da4SDimitry Andric std::string str_name(name);
113c0981da4SDimitry Andric
114c0981da4SDimitry Andric auto pos = m_subcommand_dict.find(str_name);
115c0981da4SDimitry Andric if (pos == m_subcommand_dict.end()) {
116c0981da4SDimitry Andric m_subcommand_dict[str_name] = cmd_obj_sp;
117c0981da4SDimitry Andric return llvm::Error::success();
118c0981da4SDimitry Andric }
119c0981da4SDimitry Andric
120c0981da4SDimitry Andric const char *error_str = nullptr;
121c0981da4SDimitry Andric if (!can_replace)
122c0981da4SDimitry Andric error_str = "sub-command already exists";
123c0981da4SDimitry Andric if (!(*pos).second->IsUserCommand())
124c0981da4SDimitry Andric error_str = "can't replace a builtin subcommand";
125c0981da4SDimitry Andric
126c0981da4SDimitry Andric if (error_str) {
127c0981da4SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), error_str);
128c0981da4SDimitry Andric }
129c0981da4SDimitry Andric m_subcommand_dict[str_name] = cmd_obj_sp;
130c0981da4SDimitry Andric return llvm::Error::success();
131c0981da4SDimitry Andric }
132c0981da4SDimitry Andric
RemoveUserSubcommand(llvm::StringRef cmd_name,bool must_be_multiword)133c0981da4SDimitry Andric llvm::Error CommandObjectMultiword::RemoveUserSubcommand(llvm::StringRef cmd_name,
134c0981da4SDimitry Andric bool must_be_multiword) {
135c0981da4SDimitry Andric CommandMap::iterator pos;
136c0981da4SDimitry Andric std::string str_name(cmd_name);
137c0981da4SDimitry Andric
138c0981da4SDimitry Andric pos = m_subcommand_dict.find(str_name);
139c0981da4SDimitry Andric if (pos == m_subcommand_dict.end()) {
140c0981da4SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' not found.",
141c0981da4SDimitry Andric str_name.c_str());
142c0981da4SDimitry Andric }
143c0981da4SDimitry Andric if (!(*pos).second->IsUserCommand()) {
144c0981da4SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' not a user command.",
145c0981da4SDimitry Andric str_name.c_str());
146c0981da4SDimitry Andric }
147c0981da4SDimitry Andric
148c0981da4SDimitry Andric if (must_be_multiword && !(*pos).second->IsMultiwordObject()) {
149c0981da4SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' is not a container command",
150c0981da4SDimitry Andric str_name.c_str());
151c0981da4SDimitry Andric }
152c0981da4SDimitry Andric if (!must_be_multiword && (*pos).second->IsMultiwordObject()) {
153c0981da4SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' is not a user command",
154c0981da4SDimitry Andric str_name.c_str());
155c0981da4SDimitry Andric }
156c0981da4SDimitry Andric
157c0981da4SDimitry Andric m_subcommand_dict.erase(pos);
158c0981da4SDimitry Andric
159c0981da4SDimitry Andric return llvm::Error::success();
160c0981da4SDimitry Andric }
161c0981da4SDimitry Andric
Execute(const char * args_string,CommandReturnObject & result)162b1c73532SDimitry Andric void CommandObjectMultiword::Execute(const char *args_string,
16314f1b3e8SDimitry Andric CommandReturnObject &result) {
164f034231aSEd Maste Args args(args_string);
165f034231aSEd Maste const size_t argc = args.GetArgumentCount();
16614f1b3e8SDimitry Andric if (argc == 0) {
167f034231aSEd Maste this->CommandObject::GenerateHelpText(result);
168b1c73532SDimitry Andric return;
169f034231aSEd Maste }
170f034231aSEd Maste
171ead24645SDimitry Andric auto sub_command = args[0].ref();
172ead24645SDimitry Andric if (sub_command.empty()) {
173ead24645SDimitry Andric result.AppendError("Need to specify a non-empty subcommand.");
174b1c73532SDimitry Andric return;
175ead24645SDimitry Andric }
17614f1b3e8SDimitry Andric
17714f1b3e8SDimitry Andric if (m_subcommand_dict.empty()) {
17814f1b3e8SDimitry Andric result.AppendErrorWithFormat("'%s' does not have any subcommands.\n",
17914f1b3e8SDimitry Andric GetCommandName().str().c_str());
180b1c73532SDimitry Andric return;
18114f1b3e8SDimitry Andric }
18214f1b3e8SDimitry Andric
183f034231aSEd Maste StringList matches;
184f034231aSEd Maste CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
18514f1b3e8SDimitry Andric if (sub_cmd_obj != nullptr) {
18614f1b3e8SDimitry Andric // Now call CommandObject::Execute to process options in `rest_of_line`.
187f73363f1SDimitry Andric // From there the command-specific version of Execute will be called, with
188f73363f1SDimitry Andric // the processed arguments.
189f034231aSEd Maste
190f034231aSEd Maste args.Shift();
191f034231aSEd Maste sub_cmd_obj->Execute(args_string, result);
192b1c73532SDimitry Andric return;
193f034231aSEd Maste }
19414f1b3e8SDimitry Andric
195f034231aSEd Maste std::string error_msg;
196f034231aSEd Maste const size_t num_subcmd_matches = matches.GetSize();
197f034231aSEd Maste if (num_subcmd_matches > 0)
198f034231aSEd Maste error_msg.assign("ambiguous command ");
199f034231aSEd Maste else
200f034231aSEd Maste error_msg.assign("invalid command ");
201f034231aSEd Maste
202f034231aSEd Maste error_msg.append("'");
203cfca06d7SDimitry Andric error_msg.append(std::string(GetCommandName()));
204f034231aSEd Maste error_msg.append(" ");
205cfca06d7SDimitry Andric error_msg.append(std::string(sub_command));
2065e95aa85SEd Maste error_msg.append("'.");
207f034231aSEd Maste
20814f1b3e8SDimitry Andric if (num_subcmd_matches > 0) {
209f034231aSEd Maste error_msg.append(" Possible completions:");
210ead24645SDimitry Andric for (const std::string &match : matches) {
211f034231aSEd Maste error_msg.append("\n\t");
212ead24645SDimitry Andric error_msg.append(match);
213f034231aSEd Maste }
214f034231aSEd Maste }
215f034231aSEd Maste error_msg.append("\n");
216f034231aSEd Maste result.AppendRawError(error_msg.c_str());
217f034231aSEd Maste }
218f034231aSEd Maste
GenerateHelpText(Stream & output_stream)21914f1b3e8SDimitry Andric void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
220f73363f1SDimitry Andric // First time through here, generate the help text for the object and push it
221f73363f1SDimitry Andric // to the return result object as well
222f034231aSEd Maste
223f3fbd1c0SDimitry Andric CommandObject::GenerateHelpText(output_stream);
224f3fbd1c0SDimitry Andric output_stream.PutCString("\nThe following subcommands are supported:\n\n");
225f034231aSEd Maste
226f034231aSEd Maste CommandMap::iterator pos;
227f3fbd1c0SDimitry Andric uint32_t max_len = FindLongestCommandWord(m_subcommand_dict);
228f034231aSEd Maste
229f034231aSEd Maste if (max_len)
230f034231aSEd Maste max_len += 4; // Indent the output by 4 spaces.
231f034231aSEd Maste
23214f1b3e8SDimitry Andric for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) {
233f034231aSEd Maste std::string indented_command(" ");
234f034231aSEd Maste indented_command.append(pos->first);
23514f1b3e8SDimitry Andric if (pos->second->WantsRawCommandString()) {
236cfca06d7SDimitry Andric std::string help_text(std::string(pos->second->GetHelp()));
237f3fbd1c0SDimitry Andric help_text.append(" Expects 'raw' input (see 'help raw-input'.)");
238cfca06d7SDimitry Andric m_interpreter.OutputFormattedHelpText(output_stream, indented_command,
239cfca06d7SDimitry Andric "--", help_text, max_len);
24014f1b3e8SDimitry Andric } else
241cfca06d7SDimitry Andric m_interpreter.OutputFormattedHelpText(output_stream, indented_command,
242cfca06d7SDimitry Andric "--", pos->second->GetHelp(),
243cfca06d7SDimitry Andric max_len);
244f034231aSEd Maste }
245f034231aSEd Maste
24614f1b3e8SDimitry Andric output_stream.PutCString("\nFor more help on any particular subcommand, type "
24714f1b3e8SDimitry Andric "'help <command> <subcommand>'.\n");
248f034231aSEd Maste }
249f034231aSEd Maste
HandleCompletion(CompletionRequest & request)250ead24645SDimitry Andric void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
251ead24645SDimitry Andric auto arg0 = request.GetParsedLine()[0].ref();
252f73363f1SDimitry Andric if (request.GetCursorIndex() == 0) {
25394994d37SDimitry Andric StringList new_matches, descriptions;
25494994d37SDimitry Andric AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches,
25594994d37SDimitry Andric &descriptions);
25694994d37SDimitry Andric request.AddCompletions(new_matches, descriptions);
257f034231aSEd Maste
25839be7ce2SDimitry Andric if (new_matches.GetSize() == 1 &&
25939be7ce2SDimitry Andric new_matches.GetStringAtIndex(0) != nullptr &&
26039be7ce2SDimitry Andric (arg0 == new_matches.GetStringAtIndex(0))) {
261f034231aSEd Maste StringList temp_matches;
26214f1b3e8SDimitry Andric CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
26314f1b3e8SDimitry Andric if (cmd_obj != nullptr) {
264ead24645SDimitry Andric if (request.GetParsedLine().GetArgumentCount() != 1) {
265f73363f1SDimitry Andric request.GetParsedLine().Shift();
266ead24645SDimitry Andric request.AppendEmptyArgument();
267ead24645SDimitry Andric cmd_obj->HandleCompletion(request);
268f034231aSEd Maste }
269f034231aSEd Maste }
2705e95aa85SEd Maste }
271ead24645SDimitry Andric return;
272ead24645SDimitry Andric }
273ead24645SDimitry Andric
27439be7ce2SDimitry Andric StringList new_matches;
27539be7ce2SDimitry Andric CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches);
2767fa27ce4SDimitry Andric
2777fa27ce4SDimitry Andric // The subcommand is ambiguous. The completion isn't meaningful.
2787fa27ce4SDimitry Andric if (!sub_command_object)
279ead24645SDimitry Andric return;
280ead24645SDimitry Andric
281f034231aSEd Maste // Remove the one match that we got from calling GetSubcommandObject.
28239be7ce2SDimitry Andric new_matches.DeleteStringAtIndex(0);
28339be7ce2SDimitry Andric request.AddCompletions(new_matches);
284ead24645SDimitry Andric request.ShiftArguments();
285ead24645SDimitry Andric sub_command_object->HandleCompletion(request);
286f034231aSEd Maste }
287f034231aSEd Maste
288e3b55780SDimitry Andric std::optional<std::string>
GetRepeatCommand(Args & current_command_args,uint32_t index)289145449b1SDimitry Andric CommandObjectMultiword::GetRepeatCommand(Args ¤t_command_args,
29014f1b3e8SDimitry Andric uint32_t index) {
291f034231aSEd Maste index++;
292f034231aSEd Maste if (current_command_args.GetArgumentCount() <= index)
293e3b55780SDimitry Andric return std::nullopt;
29414f1b3e8SDimitry Andric CommandObject *sub_command_object =
295ead24645SDimitry Andric GetSubcommandObject(current_command_args[index].ref());
296f3fbd1c0SDimitry Andric if (sub_command_object == nullptr)
297e3b55780SDimitry Andric return std::nullopt;
298f034231aSEd Maste return sub_command_object->GetRepeatCommand(current_command_args, index);
299f034231aSEd Maste }
300f034231aSEd Maste
CommandObjectProxy(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)301f034231aSEd Maste CommandObjectProxy::CommandObjectProxy(CommandInterpreter &interpreter,
30214f1b3e8SDimitry Andric const char *name, const char *help,
30314f1b3e8SDimitry Andric const char *syntax, uint32_t flags)
30414f1b3e8SDimitry Andric : CommandObject(interpreter, name, help, syntax, flags) {}
305f034231aSEd Maste
306f3fbd1c0SDimitry Andric CommandObjectProxy::~CommandObjectProxy() = default;
307f034231aSEd Maste
GetOptions()308b60736ecSDimitry Andric Options *CommandObjectProxy::GetOptions() {
309b60736ecSDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
310b60736ecSDimitry Andric if (proxy_command)
311b60736ecSDimitry Andric return proxy_command->GetOptions();
312b60736ecSDimitry Andric return CommandObject::GetOptions();
313b60736ecSDimitry Andric }
314b60736ecSDimitry Andric
GetHelp()315b60736ecSDimitry Andric llvm::StringRef CommandObjectProxy::GetHelp() {
316b60736ecSDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
317b60736ecSDimitry Andric if (proxy_command)
318b60736ecSDimitry Andric return proxy_command->GetHelp();
319b60736ecSDimitry Andric return CommandObject::GetHelp();
320b60736ecSDimitry Andric }
321b60736ecSDimitry Andric
GetSyntax()322b60736ecSDimitry Andric llvm::StringRef CommandObjectProxy::GetSyntax() {
323b60736ecSDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
324b60736ecSDimitry Andric if (proxy_command)
325b60736ecSDimitry Andric return proxy_command->GetSyntax();
326b60736ecSDimitry Andric return CommandObject::GetSyntax();
327b60736ecSDimitry Andric }
328b60736ecSDimitry Andric
GetHelpLong()32914f1b3e8SDimitry Andric llvm::StringRef CommandObjectProxy::GetHelpLong() {
330f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
331f034231aSEd Maste if (proxy_command)
332f034231aSEd Maste return proxy_command->GetHelpLong();
333b60736ecSDimitry Andric return CommandObject::GetHelpLong();
334f034231aSEd Maste }
335f034231aSEd Maste
IsRemovable() const33614f1b3e8SDimitry Andric bool CommandObjectProxy::IsRemovable() const {
33714f1b3e8SDimitry Andric const CommandObject *proxy_command =
33814f1b3e8SDimitry Andric const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
339f034231aSEd Maste if (proxy_command)
340f034231aSEd Maste return proxy_command->IsRemovable();
341f034231aSEd Maste return false;
342f034231aSEd Maste }
343f034231aSEd Maste
IsMultiwordObject()34414f1b3e8SDimitry Andric bool CommandObjectProxy::IsMultiwordObject() {
345f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
346f034231aSEd Maste if (proxy_command)
347f034231aSEd Maste return proxy_command->IsMultiwordObject();
348f034231aSEd Maste return false;
349f034231aSEd Maste }
350f034231aSEd Maste
GetAsMultiwordCommand()35114f1b3e8SDimitry Andric CommandObjectMultiword *CommandObjectProxy::GetAsMultiwordCommand() {
352f3fbd1c0SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
353f3fbd1c0SDimitry Andric if (proxy_command)
354f3fbd1c0SDimitry Andric return proxy_command->GetAsMultiwordCommand();
355f3fbd1c0SDimitry Andric return nullptr;
356f3fbd1c0SDimitry Andric }
357f3fbd1c0SDimitry Andric
GenerateHelpText(Stream & result)35814f1b3e8SDimitry Andric void CommandObjectProxy::GenerateHelpText(Stream &result) {
359e81d9d49SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
360e81d9d49SDimitry Andric if (proxy_command)
361b60736ecSDimitry Andric proxy_command->GenerateHelpText(result);
362b60736ecSDimitry Andric else
363b60736ecSDimitry Andric CommandObject::GenerateHelpText(result);
364e81d9d49SDimitry Andric }
365e81d9d49SDimitry Andric
366f034231aSEd Maste lldb::CommandObjectSP
GetSubcommandSP(llvm::StringRef sub_cmd,StringList * matches)36714f1b3e8SDimitry Andric CommandObjectProxy::GetSubcommandSP(llvm::StringRef sub_cmd,
36814f1b3e8SDimitry Andric StringList *matches) {
369f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
370f034231aSEd Maste if (proxy_command)
371f034231aSEd Maste return proxy_command->GetSubcommandSP(sub_cmd, matches);
372f034231aSEd Maste return lldb::CommandObjectSP();
373f034231aSEd Maste }
374f034231aSEd Maste
GetSubcommandObject(llvm::StringRef sub_cmd,StringList * matches)37514f1b3e8SDimitry Andric CommandObject *CommandObjectProxy::GetSubcommandObject(llvm::StringRef sub_cmd,
37614f1b3e8SDimitry Andric StringList *matches) {
377f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
378f034231aSEd Maste if (proxy_command)
379f034231aSEd Maste return proxy_command->GetSubcommandObject(sub_cmd, matches);
380f3fbd1c0SDimitry Andric return nullptr;
381f034231aSEd Maste }
382f034231aSEd Maste
LoadSubCommand(llvm::StringRef cmd_name,const lldb::CommandObjectSP & command_sp)38314f1b3e8SDimitry Andric bool CommandObjectProxy::LoadSubCommand(
38414f1b3e8SDimitry Andric llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_sp) {
385f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
386f034231aSEd Maste if (proxy_command)
387f034231aSEd Maste return proxy_command->LoadSubCommand(cmd_name, command_sp);
388f034231aSEd Maste return false;
389f034231aSEd Maste }
390f034231aSEd Maste
WantsRawCommandString()39114f1b3e8SDimitry Andric bool CommandObjectProxy::WantsRawCommandString() {
392f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
393f034231aSEd Maste if (proxy_command)
394f034231aSEd Maste return proxy_command->WantsRawCommandString();
395f034231aSEd Maste return false;
396f034231aSEd Maste }
397f034231aSEd Maste
WantsCompletion()39814f1b3e8SDimitry Andric bool CommandObjectProxy::WantsCompletion() {
399f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
400f034231aSEd Maste if (proxy_command)
401f034231aSEd Maste return proxy_command->WantsCompletion();
402f034231aSEd Maste return false;
403f034231aSEd Maste }
404f034231aSEd Maste
HandleCompletion(CompletionRequest & request)405ead24645SDimitry Andric void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
406f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
407f034231aSEd Maste if (proxy_command)
408ead24645SDimitry Andric proxy_command->HandleCompletion(request);
409f034231aSEd Maste }
410f3fbd1c0SDimitry Andric
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)411ead24645SDimitry Andric void CommandObjectProxy::HandleArgumentCompletion(
412f73363f1SDimitry Andric CompletionRequest &request, OptionElementVector &opt_element_vector) {
413f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
414f034231aSEd Maste if (proxy_command)
415ead24645SDimitry Andric proxy_command->HandleArgumentCompletion(request, opt_element_vector);
416f034231aSEd Maste }
417f034231aSEd Maste
418e3b55780SDimitry Andric std::optional<std::string>
GetRepeatCommand(Args & current_command_args,uint32_t index)419145449b1SDimitry Andric CommandObjectProxy::GetRepeatCommand(Args ¤t_command_args,
42014f1b3e8SDimitry Andric uint32_t index) {
421f034231aSEd Maste CommandObject *proxy_command = GetProxyCommandObject();
422f034231aSEd Maste if (proxy_command)
423f034231aSEd Maste return proxy_command->GetRepeatCommand(current_command_args, index);
424e3b55780SDimitry Andric return std::nullopt;
425f034231aSEd Maste }
426f034231aSEd Maste
GetUnsupportedError()427b60736ecSDimitry Andric llvm::StringRef CommandObjectProxy::GetUnsupportedError() {
428b60736ecSDimitry Andric return "command is not implemented";
429b60736ecSDimitry Andric }
430b60736ecSDimitry Andric
Execute(const char * args_string,CommandReturnObject & result)431b1c73532SDimitry Andric void CommandObjectProxy::Execute(const char *args_string,
43214f1b3e8SDimitry Andric CommandReturnObject &result) {
433b1c73532SDimitry Andric if (CommandObject *proxy_command = GetProxyCommandObject())
434b1c73532SDimitry Andric proxy_command->Execute(args_string, result);
435b1c73532SDimitry Andric else
436344a3780SDimitry Andric result.AppendError(GetUnsupportedError());
437f034231aSEd Maste }
438