15ffd83dbSDimitry Andric //===-- CommandObjectMultiword.cpp ----------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "lldb/Interpreter/CommandObjectMultiword.h"
100b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
110b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
120b57cec5SDimitry Andric #include "lldb/Interpreter/Options.h"
13bdd1243dSDimitry Andric #include <optional>
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric using namespace lldb;
160b57cec5SDimitry Andric using namespace lldb_private;
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric // CommandObjectMultiword
190b57cec5SDimitry Andric
CommandObjectMultiword(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)200b57cec5SDimitry Andric CommandObjectMultiword::CommandObjectMultiword(CommandInterpreter &interpreter,
210b57cec5SDimitry Andric const char *name,
220b57cec5SDimitry Andric const char *help,
230b57cec5SDimitry Andric const char *syntax,
240b57cec5SDimitry Andric uint32_t flags)
250b57cec5SDimitry Andric : CommandObject(interpreter, name, help, syntax, flags),
260b57cec5SDimitry Andric m_can_be_removed(false) {}
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric CommandObjectMultiword::~CommandObjectMultiword() = default;
290b57cec5SDimitry Andric
30349cc55cSDimitry Andric CommandObjectSP
GetSubcommandSPExact(llvm::StringRef sub_cmd)31349cc55cSDimitry Andric CommandObjectMultiword::GetSubcommandSPExact(llvm::StringRef sub_cmd) {
32349cc55cSDimitry Andric if (m_subcommand_dict.empty())
33349cc55cSDimitry Andric return {};
34349cc55cSDimitry Andric
35349cc55cSDimitry Andric auto pos = m_subcommand_dict.find(std::string(sub_cmd));
36349cc55cSDimitry Andric if (pos == m_subcommand_dict.end())
37349cc55cSDimitry Andric return {};
38349cc55cSDimitry Andric
39349cc55cSDimitry Andric return pos->second;
40349cc55cSDimitry Andric }
41349cc55cSDimitry Andric
GetSubcommandSP(llvm::StringRef sub_cmd,StringList * matches)420b57cec5SDimitry Andric CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd,
430b57cec5SDimitry Andric StringList *matches) {
44349cc55cSDimitry Andric if (m_subcommand_dict.empty())
45349cc55cSDimitry Andric return {};
460b57cec5SDimitry Andric
47349cc55cSDimitry Andric CommandObjectSP return_cmd_sp = GetSubcommandSPExact(sub_cmd);
48349cc55cSDimitry Andric if (return_cmd_sp) {
490b57cec5SDimitry Andric if (matches)
500b57cec5SDimitry Andric matches->AppendString(sub_cmd);
51349cc55cSDimitry Andric return return_cmd_sp;
52349cc55cSDimitry Andric }
53349cc55cSDimitry Andric
54349cc55cSDimitry Andric CommandObject::CommandMap::iterator pos;
55349cc55cSDimitry Andric
560b57cec5SDimitry Andric StringList local_matches;
570b57cec5SDimitry Andric if (matches == nullptr)
580b57cec5SDimitry Andric matches = &local_matches;
590b57cec5SDimitry Andric int num_matches =
600b57cec5SDimitry Andric AddNamesMatchingPartialString(m_subcommand_dict, sub_cmd, *matches);
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric if (num_matches == 1) {
630b57cec5SDimitry Andric // Cleaner, but slightly less efficient would be to call back into this
640b57cec5SDimitry Andric // function, since I now know I have an exact match...
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric sub_cmd = matches->GetStringAtIndex(0);
675ffd83dbSDimitry Andric pos = m_subcommand_dict.find(std::string(sub_cmd));
680b57cec5SDimitry Andric if (pos != m_subcommand_dict.end())
690b57cec5SDimitry Andric return_cmd_sp = pos->second;
700b57cec5SDimitry Andric }
71349cc55cSDimitry Andric
720b57cec5SDimitry Andric return return_cmd_sp;
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric CommandObject *
GetSubcommandObject(llvm::StringRef sub_cmd,StringList * matches)760b57cec5SDimitry Andric CommandObjectMultiword::GetSubcommandObject(llvm::StringRef sub_cmd,
770b57cec5SDimitry Andric StringList *matches) {
780b57cec5SDimitry Andric return GetSubcommandSP(sub_cmd, matches).get();
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric
LoadSubCommand(llvm::StringRef name,const CommandObjectSP & cmd_obj_sp)810b57cec5SDimitry Andric bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name,
82349cc55cSDimitry Andric const CommandObjectSP &cmd_obj_sp) {
83349cc55cSDimitry Andric if (cmd_obj_sp)
84349cc55cSDimitry Andric lldbassert((&GetCommandInterpreter() == &cmd_obj_sp->GetCommandInterpreter()) &&
850b57cec5SDimitry Andric "tried to add a CommandObject from a different interpreter");
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric CommandMap::iterator pos;
880b57cec5SDimitry Andric bool success = true;
890b57cec5SDimitry Andric
905ffd83dbSDimitry Andric pos = m_subcommand_dict.find(std::string(name));
910b57cec5SDimitry Andric if (pos == m_subcommand_dict.end()) {
92349cc55cSDimitry Andric m_subcommand_dict[std::string(name)] = cmd_obj_sp;
930b57cec5SDimitry Andric } else
940b57cec5SDimitry Andric success = false;
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric return success;
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric
LoadUserSubcommand(llvm::StringRef name,const CommandObjectSP & cmd_obj_sp,bool can_replace)99349cc55cSDimitry Andric llvm::Error CommandObjectMultiword::LoadUserSubcommand(
100349cc55cSDimitry Andric llvm::StringRef name, const CommandObjectSP &cmd_obj_sp, bool can_replace) {
101349cc55cSDimitry Andric Status result;
102349cc55cSDimitry Andric if (cmd_obj_sp)
103349cc55cSDimitry Andric lldbassert((&GetCommandInterpreter() == &cmd_obj_sp->GetCommandInterpreter()) &&
104349cc55cSDimitry Andric "tried to add a CommandObject from a different interpreter");
105349cc55cSDimitry Andric if (!IsUserCommand()) {
106349cc55cSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
107349cc55cSDimitry Andric "can't add a user subcommand to a builtin container command.");
108349cc55cSDimitry Andric }
109349cc55cSDimitry Andric // Make sure this a user command if it isn't already:
110349cc55cSDimitry Andric cmd_obj_sp->SetIsUserCommand(true);
111349cc55cSDimitry Andric
112349cc55cSDimitry Andric std::string str_name(name);
113349cc55cSDimitry Andric
114349cc55cSDimitry Andric auto pos = m_subcommand_dict.find(str_name);
115349cc55cSDimitry Andric if (pos == m_subcommand_dict.end()) {
116349cc55cSDimitry Andric m_subcommand_dict[str_name] = cmd_obj_sp;
117349cc55cSDimitry Andric return llvm::Error::success();
118349cc55cSDimitry Andric }
119349cc55cSDimitry Andric
120349cc55cSDimitry Andric const char *error_str = nullptr;
121349cc55cSDimitry Andric if (!can_replace)
122349cc55cSDimitry Andric error_str = "sub-command already exists";
123349cc55cSDimitry Andric if (!(*pos).second->IsUserCommand())
124349cc55cSDimitry Andric error_str = "can't replace a builtin subcommand";
125349cc55cSDimitry Andric
126349cc55cSDimitry Andric if (error_str) {
127349cc55cSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), error_str);
128349cc55cSDimitry Andric }
129349cc55cSDimitry Andric m_subcommand_dict[str_name] = cmd_obj_sp;
130349cc55cSDimitry Andric return llvm::Error::success();
131349cc55cSDimitry Andric }
132349cc55cSDimitry Andric
RemoveUserSubcommand(llvm::StringRef cmd_name,bool must_be_multiword)133349cc55cSDimitry Andric llvm::Error CommandObjectMultiword::RemoveUserSubcommand(llvm::StringRef cmd_name,
134349cc55cSDimitry Andric bool must_be_multiword) {
135349cc55cSDimitry Andric CommandMap::iterator pos;
136349cc55cSDimitry Andric std::string str_name(cmd_name);
137349cc55cSDimitry Andric
138349cc55cSDimitry Andric pos = m_subcommand_dict.find(str_name);
139349cc55cSDimitry Andric if (pos == m_subcommand_dict.end()) {
140349cc55cSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' not found.",
141349cc55cSDimitry Andric str_name.c_str());
142349cc55cSDimitry Andric }
143349cc55cSDimitry Andric if (!(*pos).second->IsUserCommand()) {
144349cc55cSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' not a user command.",
145349cc55cSDimitry Andric str_name.c_str());
146349cc55cSDimitry Andric }
147349cc55cSDimitry Andric
148349cc55cSDimitry Andric if (must_be_multiword && !(*pos).second->IsMultiwordObject()) {
149349cc55cSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' is not a container command",
150349cc55cSDimitry Andric str_name.c_str());
151349cc55cSDimitry Andric }
152349cc55cSDimitry Andric if (!must_be_multiword && (*pos).second->IsMultiwordObject()) {
153349cc55cSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' is not a user command",
154349cc55cSDimitry Andric str_name.c_str());
155349cc55cSDimitry Andric }
156349cc55cSDimitry Andric
157349cc55cSDimitry Andric m_subcommand_dict.erase(pos);
158349cc55cSDimitry Andric
159349cc55cSDimitry Andric return llvm::Error::success();
160349cc55cSDimitry Andric }
161349cc55cSDimitry Andric
Execute(const char * args_string,CommandReturnObject & result)162*5f757f3fSDimitry Andric void CommandObjectMultiword::Execute(const char *args_string,
1630b57cec5SDimitry Andric CommandReturnObject &result) {
1640b57cec5SDimitry Andric Args args(args_string);
1650b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount();
1660b57cec5SDimitry Andric if (argc == 0) {
1670b57cec5SDimitry Andric this->CommandObject::GenerateHelpText(result);
168*5f757f3fSDimitry Andric return;
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric
1719dba64beSDimitry Andric auto sub_command = args[0].ref();
1729dba64beSDimitry Andric if (sub_command.empty()) {
1739dba64beSDimitry Andric result.AppendError("Need to specify a non-empty subcommand.");
174*5f757f3fSDimitry Andric return;
1759dba64beSDimitry Andric }
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric if (m_subcommand_dict.empty()) {
1780b57cec5SDimitry Andric result.AppendErrorWithFormat("'%s' does not have any subcommands.\n",
1790b57cec5SDimitry Andric GetCommandName().str().c_str());
180*5f757f3fSDimitry Andric return;
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andric StringList matches;
1840b57cec5SDimitry Andric CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
1850b57cec5SDimitry Andric if (sub_cmd_obj != nullptr) {
1860b57cec5SDimitry Andric // Now call CommandObject::Execute to process options in `rest_of_line`.
1870b57cec5SDimitry Andric // From there the command-specific version of Execute will be called, with
1880b57cec5SDimitry Andric // the processed arguments.
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andric args.Shift();
1910b57cec5SDimitry Andric sub_cmd_obj->Execute(args_string, result);
192*5f757f3fSDimitry Andric return;
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric std::string error_msg;
1960b57cec5SDimitry Andric const size_t num_subcmd_matches = matches.GetSize();
1970b57cec5SDimitry Andric if (num_subcmd_matches > 0)
1980b57cec5SDimitry Andric error_msg.assign("ambiguous command ");
1990b57cec5SDimitry Andric else
2000b57cec5SDimitry Andric error_msg.assign("invalid command ");
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric error_msg.append("'");
2035ffd83dbSDimitry Andric error_msg.append(std::string(GetCommandName()));
2040b57cec5SDimitry Andric error_msg.append(" ");
2055ffd83dbSDimitry Andric error_msg.append(std::string(sub_command));
2060b57cec5SDimitry Andric error_msg.append("'.");
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric if (num_subcmd_matches > 0) {
2090b57cec5SDimitry Andric error_msg.append(" Possible completions:");
2109dba64beSDimitry Andric for (const std::string &match : matches) {
2110b57cec5SDimitry Andric error_msg.append("\n\t");
2129dba64beSDimitry Andric error_msg.append(match);
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric error_msg.append("\n");
2160b57cec5SDimitry Andric result.AppendRawError(error_msg.c_str());
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric
GenerateHelpText(Stream & output_stream)2190b57cec5SDimitry Andric void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
2200b57cec5SDimitry Andric // First time through here, generate the help text for the object and push it
2210b57cec5SDimitry Andric // to the return result object as well
2220b57cec5SDimitry Andric
2230b57cec5SDimitry Andric CommandObject::GenerateHelpText(output_stream);
2240b57cec5SDimitry Andric output_stream.PutCString("\nThe following subcommands are supported:\n\n");
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric CommandMap::iterator pos;
2270b57cec5SDimitry Andric uint32_t max_len = FindLongestCommandWord(m_subcommand_dict);
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andric if (max_len)
2300b57cec5SDimitry Andric max_len += 4; // Indent the output by 4 spaces.
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) {
2330b57cec5SDimitry Andric std::string indented_command(" ");
2340b57cec5SDimitry Andric indented_command.append(pos->first);
2350b57cec5SDimitry Andric if (pos->second->WantsRawCommandString()) {
2365ffd83dbSDimitry Andric std::string help_text(std::string(pos->second->GetHelp()));
2370b57cec5SDimitry Andric help_text.append(" Expects 'raw' input (see 'help raw-input'.)");
2385ffd83dbSDimitry Andric m_interpreter.OutputFormattedHelpText(output_stream, indented_command,
2395ffd83dbSDimitry Andric "--", help_text, max_len);
2400b57cec5SDimitry Andric } else
2415ffd83dbSDimitry Andric m_interpreter.OutputFormattedHelpText(output_stream, indented_command,
2425ffd83dbSDimitry Andric "--", pos->second->GetHelp(),
2435ffd83dbSDimitry Andric max_len);
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andric output_stream.PutCString("\nFor more help on any particular subcommand, type "
2470b57cec5SDimitry Andric "'help <command> <subcommand>'.\n");
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric
HandleCompletion(CompletionRequest & request)2509dba64beSDimitry Andric void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
2519dba64beSDimitry Andric auto arg0 = request.GetParsedLine()[0].ref();
2520b57cec5SDimitry Andric if (request.GetCursorIndex() == 0) {
2530b57cec5SDimitry Andric StringList new_matches, descriptions;
2540b57cec5SDimitry Andric AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches,
2550b57cec5SDimitry Andric &descriptions);
2560b57cec5SDimitry Andric request.AddCompletions(new_matches, descriptions);
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric if (new_matches.GetSize() == 1 &&
2590b57cec5SDimitry Andric new_matches.GetStringAtIndex(0) != nullptr &&
2600b57cec5SDimitry Andric (arg0 == new_matches.GetStringAtIndex(0))) {
2610b57cec5SDimitry Andric StringList temp_matches;
2620b57cec5SDimitry Andric CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
2630b57cec5SDimitry Andric if (cmd_obj != nullptr) {
2649dba64beSDimitry Andric if (request.GetParsedLine().GetArgumentCount() != 1) {
2650b57cec5SDimitry Andric request.GetParsedLine().Shift();
2669dba64beSDimitry Andric request.AppendEmptyArgument();
2679dba64beSDimitry Andric cmd_obj->HandleCompletion(request);
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric }
2719dba64beSDimitry Andric return;
2729dba64beSDimitry Andric }
2739dba64beSDimitry Andric
2740b57cec5SDimitry Andric StringList new_matches;
2750b57cec5SDimitry Andric CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches);
27606c3fb27SDimitry Andric
27706c3fb27SDimitry Andric // The subcommand is ambiguous. The completion isn't meaningful.
27806c3fb27SDimitry Andric if (!sub_command_object)
2799dba64beSDimitry Andric return;
2809dba64beSDimitry Andric
2810b57cec5SDimitry Andric // Remove the one match that we got from calling GetSubcommandObject.
2820b57cec5SDimitry Andric new_matches.DeleteStringAtIndex(0);
2830b57cec5SDimitry Andric request.AddCompletions(new_matches);
2849dba64beSDimitry Andric request.ShiftArguments();
2859dba64beSDimitry Andric sub_command_object->HandleCompletion(request);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric
288bdd1243dSDimitry Andric std::optional<std::string>
GetRepeatCommand(Args & current_command_args,uint32_t index)28981ad6265SDimitry Andric CommandObjectMultiword::GetRepeatCommand(Args ¤t_command_args,
2900b57cec5SDimitry Andric uint32_t index) {
2910b57cec5SDimitry Andric index++;
2920b57cec5SDimitry Andric if (current_command_args.GetArgumentCount() <= index)
293bdd1243dSDimitry Andric return std::nullopt;
2940b57cec5SDimitry Andric CommandObject *sub_command_object =
2959dba64beSDimitry Andric GetSubcommandObject(current_command_args[index].ref());
2960b57cec5SDimitry Andric if (sub_command_object == nullptr)
297bdd1243dSDimitry Andric return std::nullopt;
2980b57cec5SDimitry Andric return sub_command_object->GetRepeatCommand(current_command_args, index);
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric
CommandObjectProxy(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)3010b57cec5SDimitry Andric CommandObjectProxy::CommandObjectProxy(CommandInterpreter &interpreter,
3020b57cec5SDimitry Andric const char *name, const char *help,
3030b57cec5SDimitry Andric const char *syntax, uint32_t flags)
3040b57cec5SDimitry Andric : CommandObject(interpreter, name, help, syntax, flags) {}
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric CommandObjectProxy::~CommandObjectProxy() = default;
3070b57cec5SDimitry Andric
GetOptions()308e8d8bef9SDimitry Andric Options *CommandObjectProxy::GetOptions() {
309e8d8bef9SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
310e8d8bef9SDimitry Andric if (proxy_command)
311e8d8bef9SDimitry Andric return proxy_command->GetOptions();
312e8d8bef9SDimitry Andric return CommandObject::GetOptions();
313e8d8bef9SDimitry Andric }
314e8d8bef9SDimitry Andric
GetHelp()315e8d8bef9SDimitry Andric llvm::StringRef CommandObjectProxy::GetHelp() {
316e8d8bef9SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
317e8d8bef9SDimitry Andric if (proxy_command)
318e8d8bef9SDimitry Andric return proxy_command->GetHelp();
319e8d8bef9SDimitry Andric return CommandObject::GetHelp();
320e8d8bef9SDimitry Andric }
321e8d8bef9SDimitry Andric
GetSyntax()322e8d8bef9SDimitry Andric llvm::StringRef CommandObjectProxy::GetSyntax() {
323e8d8bef9SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
324e8d8bef9SDimitry Andric if (proxy_command)
325e8d8bef9SDimitry Andric return proxy_command->GetSyntax();
326e8d8bef9SDimitry Andric return CommandObject::GetSyntax();
327e8d8bef9SDimitry Andric }
328e8d8bef9SDimitry Andric
GetHelpLong()3290b57cec5SDimitry Andric llvm::StringRef CommandObjectProxy::GetHelpLong() {
3300b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3310b57cec5SDimitry Andric if (proxy_command)
3320b57cec5SDimitry Andric return proxy_command->GetHelpLong();
333e8d8bef9SDimitry Andric return CommandObject::GetHelpLong();
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric
IsRemovable() const3360b57cec5SDimitry Andric bool CommandObjectProxy::IsRemovable() const {
3370b57cec5SDimitry Andric const CommandObject *proxy_command =
3380b57cec5SDimitry Andric const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
3390b57cec5SDimitry Andric if (proxy_command)
3400b57cec5SDimitry Andric return proxy_command->IsRemovable();
3410b57cec5SDimitry Andric return false;
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric
IsMultiwordObject()3440b57cec5SDimitry Andric bool CommandObjectProxy::IsMultiwordObject() {
3450b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3460b57cec5SDimitry Andric if (proxy_command)
3470b57cec5SDimitry Andric return proxy_command->IsMultiwordObject();
3480b57cec5SDimitry Andric return false;
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric
GetAsMultiwordCommand()3510b57cec5SDimitry Andric CommandObjectMultiword *CommandObjectProxy::GetAsMultiwordCommand() {
3520b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3530b57cec5SDimitry Andric if (proxy_command)
3540b57cec5SDimitry Andric return proxy_command->GetAsMultiwordCommand();
3550b57cec5SDimitry Andric return nullptr;
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric
GenerateHelpText(Stream & result)3580b57cec5SDimitry Andric void CommandObjectProxy::GenerateHelpText(Stream &result) {
3590b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3600b57cec5SDimitry Andric if (proxy_command)
361e8d8bef9SDimitry Andric proxy_command->GenerateHelpText(result);
362e8d8bef9SDimitry Andric else
363e8d8bef9SDimitry Andric CommandObject::GenerateHelpText(result);
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andric lldb::CommandObjectSP
GetSubcommandSP(llvm::StringRef sub_cmd,StringList * matches)3670b57cec5SDimitry Andric CommandObjectProxy::GetSubcommandSP(llvm::StringRef sub_cmd,
3680b57cec5SDimitry Andric StringList *matches) {
3690b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3700b57cec5SDimitry Andric if (proxy_command)
3710b57cec5SDimitry Andric return proxy_command->GetSubcommandSP(sub_cmd, matches);
3720b57cec5SDimitry Andric return lldb::CommandObjectSP();
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric
GetSubcommandObject(llvm::StringRef sub_cmd,StringList * matches)3750b57cec5SDimitry Andric CommandObject *CommandObjectProxy::GetSubcommandObject(llvm::StringRef sub_cmd,
3760b57cec5SDimitry Andric StringList *matches) {
3770b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3780b57cec5SDimitry Andric if (proxy_command)
3790b57cec5SDimitry Andric return proxy_command->GetSubcommandObject(sub_cmd, matches);
3800b57cec5SDimitry Andric return nullptr;
3810b57cec5SDimitry Andric }
3820b57cec5SDimitry Andric
LoadSubCommand(llvm::StringRef cmd_name,const lldb::CommandObjectSP & command_sp)3830b57cec5SDimitry Andric bool CommandObjectProxy::LoadSubCommand(
3840b57cec5SDimitry Andric llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_sp) {
3850b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3860b57cec5SDimitry Andric if (proxy_command)
3870b57cec5SDimitry Andric return proxy_command->LoadSubCommand(cmd_name, command_sp);
3880b57cec5SDimitry Andric return false;
3890b57cec5SDimitry Andric }
3900b57cec5SDimitry Andric
WantsRawCommandString()3910b57cec5SDimitry Andric bool CommandObjectProxy::WantsRawCommandString() {
3920b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
3930b57cec5SDimitry Andric if (proxy_command)
3940b57cec5SDimitry Andric return proxy_command->WantsRawCommandString();
3950b57cec5SDimitry Andric return false;
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric
WantsCompletion()3980b57cec5SDimitry Andric bool CommandObjectProxy::WantsCompletion() {
3990b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
4000b57cec5SDimitry Andric if (proxy_command)
4010b57cec5SDimitry Andric return proxy_command->WantsCompletion();
4020b57cec5SDimitry Andric return false;
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric
HandleCompletion(CompletionRequest & request)4059dba64beSDimitry Andric void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
4060b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
4070b57cec5SDimitry Andric if (proxy_command)
4089dba64beSDimitry Andric proxy_command->HandleCompletion(request);
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)4119dba64beSDimitry Andric void CommandObjectProxy::HandleArgumentCompletion(
4120b57cec5SDimitry Andric CompletionRequest &request, OptionElementVector &opt_element_vector) {
4130b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
4140b57cec5SDimitry Andric if (proxy_command)
4159dba64beSDimitry Andric proxy_command->HandleArgumentCompletion(request, opt_element_vector);
4160b57cec5SDimitry Andric }
4170b57cec5SDimitry Andric
418bdd1243dSDimitry Andric std::optional<std::string>
GetRepeatCommand(Args & current_command_args,uint32_t index)41981ad6265SDimitry Andric CommandObjectProxy::GetRepeatCommand(Args ¤t_command_args,
4200b57cec5SDimitry Andric uint32_t index) {
4210b57cec5SDimitry Andric CommandObject *proxy_command = GetProxyCommandObject();
4220b57cec5SDimitry Andric if (proxy_command)
4230b57cec5SDimitry Andric return proxy_command->GetRepeatCommand(current_command_args, index);
424bdd1243dSDimitry Andric return std::nullopt;
4250b57cec5SDimitry Andric }
4260b57cec5SDimitry Andric
GetUnsupportedError()427e8d8bef9SDimitry Andric llvm::StringRef CommandObjectProxy::GetUnsupportedError() {
428e8d8bef9SDimitry Andric return "command is not implemented";
429e8d8bef9SDimitry Andric }
430e8d8bef9SDimitry Andric
Execute(const char * args_string,CommandReturnObject & result)431*5f757f3fSDimitry Andric void CommandObjectProxy::Execute(const char *args_string,
4320b57cec5SDimitry Andric CommandReturnObject &result) {
433*5f757f3fSDimitry Andric if (CommandObject *proxy_command = GetProxyCommandObject())
434*5f757f3fSDimitry Andric proxy_command->Execute(args_string, result);
435*5f757f3fSDimitry Andric else
436fe6060f1SDimitry Andric result.AppendError(GetUnsupportedError());
4370b57cec5SDimitry Andric }
438