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"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric using namespace lldb;
150b57cec5SDimitry Andric using namespace lldb_private;
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric // CommandObjectMultiword
180b57cec5SDimitry Andric 
CommandObjectMultiword(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)190b57cec5SDimitry Andric CommandObjectMultiword::CommandObjectMultiword(CommandInterpreter &interpreter,
200b57cec5SDimitry Andric                                                const char *name,
210b57cec5SDimitry Andric                                                const char *help,
220b57cec5SDimitry Andric                                                const char *syntax,
230b57cec5SDimitry Andric                                                uint32_t flags)
240b57cec5SDimitry Andric     : CommandObject(interpreter, name, help, syntax, flags),
250b57cec5SDimitry Andric       m_can_be_removed(false) {}
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric CommandObjectMultiword::~CommandObjectMultiword() = default;
280b57cec5SDimitry Andric 
GetSubcommandSP(llvm::StringRef sub_cmd,StringList * matches)290b57cec5SDimitry Andric CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd,
300b57cec5SDimitry Andric                                                         StringList *matches) {
310b57cec5SDimitry Andric   CommandObjectSP return_cmd_sp;
320b57cec5SDimitry Andric   CommandObject::CommandMap::iterator pos;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   if (!m_subcommand_dict.empty()) {
355ffd83dbSDimitry Andric     pos = m_subcommand_dict.find(std::string(sub_cmd));
360b57cec5SDimitry Andric     if (pos != m_subcommand_dict.end()) {
370b57cec5SDimitry Andric       // An exact match; append the sub_cmd to the 'matches' string list.
380b57cec5SDimitry Andric       if (matches)
390b57cec5SDimitry Andric         matches->AppendString(sub_cmd);
400b57cec5SDimitry Andric       return_cmd_sp = pos->second;
410b57cec5SDimitry Andric     } else {
420b57cec5SDimitry Andric       StringList local_matches;
430b57cec5SDimitry Andric       if (matches == nullptr)
440b57cec5SDimitry Andric         matches = &local_matches;
450b57cec5SDimitry Andric       int num_matches =
460b57cec5SDimitry Andric           AddNamesMatchingPartialString(m_subcommand_dict, sub_cmd, *matches);
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric       if (num_matches == 1) {
490b57cec5SDimitry Andric         // Cleaner, but slightly less efficient would be to call back into this
500b57cec5SDimitry Andric         // function, since I now know I have an exact match...
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric         sub_cmd = matches->GetStringAtIndex(0);
535ffd83dbSDimitry Andric         pos = m_subcommand_dict.find(std::string(sub_cmd));
540b57cec5SDimitry Andric         if (pos != m_subcommand_dict.end())
550b57cec5SDimitry Andric           return_cmd_sp = pos->second;
560b57cec5SDimitry Andric       }
570b57cec5SDimitry Andric     }
580b57cec5SDimitry Andric   }
590b57cec5SDimitry Andric   return return_cmd_sp;
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric CommandObject *
GetSubcommandObject(llvm::StringRef sub_cmd,StringList * matches)630b57cec5SDimitry Andric CommandObjectMultiword::GetSubcommandObject(llvm::StringRef sub_cmd,
640b57cec5SDimitry Andric                                             StringList *matches) {
650b57cec5SDimitry Andric   return GetSubcommandSP(sub_cmd, matches).get();
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
LoadSubCommand(llvm::StringRef name,const CommandObjectSP & cmd_obj)680b57cec5SDimitry Andric bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name,
690b57cec5SDimitry Andric                                             const CommandObjectSP &cmd_obj) {
700b57cec5SDimitry Andric   if (cmd_obj)
710b57cec5SDimitry Andric     assert((&GetCommandInterpreter() == &cmd_obj->GetCommandInterpreter()) &&
720b57cec5SDimitry Andric            "tried to add a CommandObject from a different interpreter");
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   CommandMap::iterator pos;
750b57cec5SDimitry Andric   bool success = true;
760b57cec5SDimitry Andric 
775ffd83dbSDimitry Andric   pos = m_subcommand_dict.find(std::string(name));
780b57cec5SDimitry Andric   if (pos == m_subcommand_dict.end()) {
795ffd83dbSDimitry Andric     m_subcommand_dict[std::string(name)] = cmd_obj;
800b57cec5SDimitry Andric   } else
810b57cec5SDimitry Andric     success = false;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   return success;
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric 
Execute(const char * args_string,CommandReturnObject & result)860b57cec5SDimitry Andric bool CommandObjectMultiword::Execute(const char *args_string,
870b57cec5SDimitry Andric                                      CommandReturnObject &result) {
880b57cec5SDimitry Andric   Args args(args_string);
890b57cec5SDimitry Andric   const size_t argc = args.GetArgumentCount();
900b57cec5SDimitry Andric   if (argc == 0) {
910b57cec5SDimitry Andric     this->CommandObject::GenerateHelpText(result);
920b57cec5SDimitry Andric     return result.Succeeded();
930b57cec5SDimitry Andric   }
940b57cec5SDimitry Andric 
959dba64beSDimitry Andric   auto sub_command = args[0].ref();
969dba64beSDimitry Andric   if (sub_command.empty()) {
979dba64beSDimitry Andric     result.AppendError("Need to specify a non-empty subcommand.");
980b57cec5SDimitry Andric     return result.Succeeded();
999dba64beSDimitry Andric   }
1000b57cec5SDimitry Andric 
101*5f7ddb14SDimitry Andric   if (sub_command.equals_insensitive("help")) {
1020b57cec5SDimitry Andric     this->CommandObject::GenerateHelpText(result);
1030b57cec5SDimitry Andric     return result.Succeeded();
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   if (m_subcommand_dict.empty()) {
1070b57cec5SDimitry Andric     result.AppendErrorWithFormat("'%s' does not have any subcommands.\n",
1080b57cec5SDimitry Andric                                  GetCommandName().str().c_str());
1090b57cec5SDimitry Andric     return false;
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   StringList matches;
1130b57cec5SDimitry Andric   CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
1140b57cec5SDimitry Andric   if (sub_cmd_obj != nullptr) {
1150b57cec5SDimitry Andric     // Now call CommandObject::Execute to process options in `rest_of_line`.
1160b57cec5SDimitry Andric     // From there the command-specific version of Execute will be called, with
1170b57cec5SDimitry Andric     // the processed arguments.
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric     args.Shift();
1200b57cec5SDimitry Andric     sub_cmd_obj->Execute(args_string, result);
1210b57cec5SDimitry Andric     return result.Succeeded();
1220b57cec5SDimitry Andric   }
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   std::string error_msg;
1250b57cec5SDimitry Andric   const size_t num_subcmd_matches = matches.GetSize();
1260b57cec5SDimitry Andric   if (num_subcmd_matches > 0)
1270b57cec5SDimitry Andric     error_msg.assign("ambiguous command ");
1280b57cec5SDimitry Andric   else
1290b57cec5SDimitry Andric     error_msg.assign("invalid command ");
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   error_msg.append("'");
1325ffd83dbSDimitry Andric   error_msg.append(std::string(GetCommandName()));
1330b57cec5SDimitry Andric   error_msg.append(" ");
1345ffd83dbSDimitry Andric   error_msg.append(std::string(sub_command));
1350b57cec5SDimitry Andric   error_msg.append("'.");
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   if (num_subcmd_matches > 0) {
1380b57cec5SDimitry Andric     error_msg.append(" Possible completions:");
1399dba64beSDimitry Andric     for (const std::string &match : matches) {
1400b57cec5SDimitry Andric       error_msg.append("\n\t");
1419dba64beSDimitry Andric       error_msg.append(match);
1420b57cec5SDimitry Andric     }
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric   error_msg.append("\n");
1450b57cec5SDimitry Andric   result.AppendRawError(error_msg.c_str());
1460b57cec5SDimitry Andric   return false;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
GenerateHelpText(Stream & output_stream)1490b57cec5SDimitry Andric void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
1500b57cec5SDimitry Andric   // First time through here, generate the help text for the object and push it
1510b57cec5SDimitry Andric   // to the return result object as well
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   CommandObject::GenerateHelpText(output_stream);
1540b57cec5SDimitry Andric   output_stream.PutCString("\nThe following subcommands are supported:\n\n");
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   CommandMap::iterator pos;
1570b57cec5SDimitry Andric   uint32_t max_len = FindLongestCommandWord(m_subcommand_dict);
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   if (max_len)
1600b57cec5SDimitry Andric     max_len += 4; // Indent the output by 4 spaces.
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) {
1630b57cec5SDimitry Andric     std::string indented_command("    ");
1640b57cec5SDimitry Andric     indented_command.append(pos->first);
1650b57cec5SDimitry Andric     if (pos->second->WantsRawCommandString()) {
1665ffd83dbSDimitry Andric       std::string help_text(std::string(pos->second->GetHelp()));
1670b57cec5SDimitry Andric       help_text.append("  Expects 'raw' input (see 'help raw-input'.)");
1685ffd83dbSDimitry Andric       m_interpreter.OutputFormattedHelpText(output_stream, indented_command,
1695ffd83dbSDimitry Andric                                             "--", help_text, max_len);
1700b57cec5SDimitry Andric     } else
1715ffd83dbSDimitry Andric       m_interpreter.OutputFormattedHelpText(output_stream, indented_command,
1725ffd83dbSDimitry Andric                                             "--", pos->second->GetHelp(),
1735ffd83dbSDimitry Andric                                             max_len);
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   output_stream.PutCString("\nFor more help on any particular subcommand, type "
1770b57cec5SDimitry Andric                            "'help <command> <subcommand>'.\n");
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric 
HandleCompletion(CompletionRequest & request)1809dba64beSDimitry Andric void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
1819dba64beSDimitry Andric   auto arg0 = request.GetParsedLine()[0].ref();
1820b57cec5SDimitry Andric   if (request.GetCursorIndex() == 0) {
1830b57cec5SDimitry Andric     StringList new_matches, descriptions;
1840b57cec5SDimitry Andric     AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches,
1850b57cec5SDimitry Andric                                   &descriptions);
1860b57cec5SDimitry Andric     request.AddCompletions(new_matches, descriptions);
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric     if (new_matches.GetSize() == 1 &&
1890b57cec5SDimitry Andric         new_matches.GetStringAtIndex(0) != nullptr &&
1900b57cec5SDimitry Andric         (arg0 == new_matches.GetStringAtIndex(0))) {
1910b57cec5SDimitry Andric       StringList temp_matches;
1920b57cec5SDimitry Andric       CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
1930b57cec5SDimitry Andric       if (cmd_obj != nullptr) {
1949dba64beSDimitry Andric         if (request.GetParsedLine().GetArgumentCount() != 1) {
1950b57cec5SDimitry Andric           request.GetParsedLine().Shift();
1969dba64beSDimitry Andric           request.AppendEmptyArgument();
1979dba64beSDimitry Andric           cmd_obj->HandleCompletion(request);
1980b57cec5SDimitry Andric         }
1990b57cec5SDimitry Andric       }
2000b57cec5SDimitry Andric     }
2019dba64beSDimitry Andric     return;
2029dba64beSDimitry Andric   }
2039dba64beSDimitry Andric 
2040b57cec5SDimitry Andric   StringList new_matches;
2050b57cec5SDimitry Andric   CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches);
2060b57cec5SDimitry Andric   if (sub_command_object == nullptr) {
2070b57cec5SDimitry Andric     request.AddCompletions(new_matches);
2089dba64beSDimitry Andric     return;
2099dba64beSDimitry Andric   }
2109dba64beSDimitry Andric 
2110b57cec5SDimitry Andric   // Remove the one match that we got from calling GetSubcommandObject.
2120b57cec5SDimitry Andric   new_matches.DeleteStringAtIndex(0);
2130b57cec5SDimitry Andric   request.AddCompletions(new_matches);
2149dba64beSDimitry Andric   request.ShiftArguments();
2159dba64beSDimitry Andric   sub_command_object->HandleCompletion(request);
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
GetRepeatCommand(Args & current_command_args,uint32_t index)2180b57cec5SDimitry Andric const char *CommandObjectMultiword::GetRepeatCommand(Args &current_command_args,
2190b57cec5SDimitry Andric                                                      uint32_t index) {
2200b57cec5SDimitry Andric   index++;
2210b57cec5SDimitry Andric   if (current_command_args.GetArgumentCount() <= index)
2220b57cec5SDimitry Andric     return nullptr;
2230b57cec5SDimitry Andric   CommandObject *sub_command_object =
2249dba64beSDimitry Andric       GetSubcommandObject(current_command_args[index].ref());
2250b57cec5SDimitry Andric   if (sub_command_object == nullptr)
2260b57cec5SDimitry Andric     return nullptr;
2270b57cec5SDimitry Andric   return sub_command_object->GetRepeatCommand(current_command_args, index);
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric 
AproposAllSubCommands(llvm::StringRef prefix,llvm::StringRef search_word,StringList & commands_found,StringList & commands_help)2300b57cec5SDimitry Andric void CommandObjectMultiword::AproposAllSubCommands(llvm::StringRef prefix,
2310b57cec5SDimitry Andric                                                    llvm::StringRef search_word,
2320b57cec5SDimitry Andric                                                    StringList &commands_found,
2330b57cec5SDimitry Andric                                                    StringList &commands_help) {
2340b57cec5SDimitry Andric   CommandObject::CommandMap::const_iterator pos;
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) {
2370b57cec5SDimitry Andric     const char *command_name = pos->first.c_str();
2380b57cec5SDimitry Andric     CommandObject *sub_cmd_obj = pos->second.get();
2390b57cec5SDimitry Andric     StreamString complete_command_name;
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric     complete_command_name << prefix << " " << command_name;
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric     if (sub_cmd_obj->HelpTextContainsWord(search_word)) {
2440b57cec5SDimitry Andric       commands_found.AppendString(complete_command_name.GetString());
2450b57cec5SDimitry Andric       commands_help.AppendString(sub_cmd_obj->GetHelp());
2460b57cec5SDimitry Andric     }
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric     if (sub_cmd_obj->IsMultiwordObject())
2490b57cec5SDimitry Andric       sub_cmd_obj->AproposAllSubCommands(complete_command_name.GetString(),
2500b57cec5SDimitry Andric                                          search_word, commands_found,
2510b57cec5SDimitry Andric                                          commands_help);
2520b57cec5SDimitry Andric   }
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
CommandObjectProxy(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)2550b57cec5SDimitry Andric CommandObjectProxy::CommandObjectProxy(CommandInterpreter &interpreter,
2560b57cec5SDimitry Andric                                        const char *name, const char *help,
2570b57cec5SDimitry Andric                                        const char *syntax, uint32_t flags)
2580b57cec5SDimitry Andric     : CommandObject(interpreter, name, help, syntax, flags) {}
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric CommandObjectProxy::~CommandObjectProxy() = default;
2610b57cec5SDimitry Andric 
GetOptions()262af732203SDimitry Andric Options *CommandObjectProxy::GetOptions() {
263af732203SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
264af732203SDimitry Andric   if (proxy_command)
265af732203SDimitry Andric     return proxy_command->GetOptions();
266af732203SDimitry Andric   return CommandObject::GetOptions();
267af732203SDimitry Andric }
268af732203SDimitry Andric 
GetHelp()269af732203SDimitry Andric llvm::StringRef CommandObjectProxy::GetHelp() {
270af732203SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
271af732203SDimitry Andric   if (proxy_command)
272af732203SDimitry Andric     return proxy_command->GetHelp();
273af732203SDimitry Andric   return CommandObject::GetHelp();
274af732203SDimitry Andric }
275af732203SDimitry Andric 
GetSyntax()276af732203SDimitry Andric llvm::StringRef CommandObjectProxy::GetSyntax() {
277af732203SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
278af732203SDimitry Andric   if (proxy_command)
279af732203SDimitry Andric     return proxy_command->GetSyntax();
280af732203SDimitry Andric   return CommandObject::GetSyntax();
281af732203SDimitry Andric }
282af732203SDimitry Andric 
GetHelpLong()2830b57cec5SDimitry Andric llvm::StringRef CommandObjectProxy::GetHelpLong() {
2840b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
2850b57cec5SDimitry Andric   if (proxy_command)
2860b57cec5SDimitry Andric     return proxy_command->GetHelpLong();
287af732203SDimitry Andric   return CommandObject::GetHelpLong();
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
IsRemovable() const2900b57cec5SDimitry Andric bool CommandObjectProxy::IsRemovable() const {
2910b57cec5SDimitry Andric   const CommandObject *proxy_command =
2920b57cec5SDimitry Andric       const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
2930b57cec5SDimitry Andric   if (proxy_command)
2940b57cec5SDimitry Andric     return proxy_command->IsRemovable();
2950b57cec5SDimitry Andric   return false;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
IsMultiwordObject()2980b57cec5SDimitry Andric bool CommandObjectProxy::IsMultiwordObject() {
2990b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3000b57cec5SDimitry Andric   if (proxy_command)
3010b57cec5SDimitry Andric     return proxy_command->IsMultiwordObject();
3020b57cec5SDimitry Andric   return false;
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
GetAsMultiwordCommand()3050b57cec5SDimitry Andric CommandObjectMultiword *CommandObjectProxy::GetAsMultiwordCommand() {
3060b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3070b57cec5SDimitry Andric   if (proxy_command)
3080b57cec5SDimitry Andric     return proxy_command->GetAsMultiwordCommand();
3090b57cec5SDimitry Andric   return nullptr;
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
GenerateHelpText(Stream & result)3120b57cec5SDimitry Andric void CommandObjectProxy::GenerateHelpText(Stream &result) {
3130b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3140b57cec5SDimitry Andric   if (proxy_command)
315af732203SDimitry Andric     proxy_command->GenerateHelpText(result);
316af732203SDimitry Andric   else
317af732203SDimitry Andric     CommandObject::GenerateHelpText(result);
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric lldb::CommandObjectSP
GetSubcommandSP(llvm::StringRef sub_cmd,StringList * matches)3210b57cec5SDimitry Andric CommandObjectProxy::GetSubcommandSP(llvm::StringRef sub_cmd,
3220b57cec5SDimitry Andric                                     StringList *matches) {
3230b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3240b57cec5SDimitry Andric   if (proxy_command)
3250b57cec5SDimitry Andric     return proxy_command->GetSubcommandSP(sub_cmd, matches);
3260b57cec5SDimitry Andric   return lldb::CommandObjectSP();
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
GetSubcommandObject(llvm::StringRef sub_cmd,StringList * matches)3290b57cec5SDimitry Andric CommandObject *CommandObjectProxy::GetSubcommandObject(llvm::StringRef sub_cmd,
3300b57cec5SDimitry Andric                                                        StringList *matches) {
3310b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3320b57cec5SDimitry Andric   if (proxy_command)
3330b57cec5SDimitry Andric     return proxy_command->GetSubcommandObject(sub_cmd, matches);
3340b57cec5SDimitry Andric   return nullptr;
3350b57cec5SDimitry Andric }
3360b57cec5SDimitry Andric 
AproposAllSubCommands(llvm::StringRef prefix,llvm::StringRef search_word,StringList & commands_found,StringList & commands_help)3370b57cec5SDimitry Andric void CommandObjectProxy::AproposAllSubCommands(llvm::StringRef prefix,
3380b57cec5SDimitry Andric                                                llvm::StringRef search_word,
3390b57cec5SDimitry Andric                                                StringList &commands_found,
3400b57cec5SDimitry Andric                                                StringList &commands_help) {
3410b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3420b57cec5SDimitry Andric   if (proxy_command)
3430b57cec5SDimitry Andric     return proxy_command->AproposAllSubCommands(prefix, search_word,
3440b57cec5SDimitry Andric                                                 commands_found, commands_help);
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
LoadSubCommand(llvm::StringRef cmd_name,const lldb::CommandObjectSP & command_sp)3470b57cec5SDimitry Andric bool CommandObjectProxy::LoadSubCommand(
3480b57cec5SDimitry Andric     llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_sp) {
3490b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3500b57cec5SDimitry Andric   if (proxy_command)
3510b57cec5SDimitry Andric     return proxy_command->LoadSubCommand(cmd_name, command_sp);
3520b57cec5SDimitry Andric   return false;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
WantsRawCommandString()3550b57cec5SDimitry Andric bool CommandObjectProxy::WantsRawCommandString() {
3560b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3570b57cec5SDimitry Andric   if (proxy_command)
3580b57cec5SDimitry Andric     return proxy_command->WantsRawCommandString();
3590b57cec5SDimitry Andric   return false;
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
WantsCompletion()3620b57cec5SDimitry Andric bool CommandObjectProxy::WantsCompletion() {
3630b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3640b57cec5SDimitry Andric   if (proxy_command)
3650b57cec5SDimitry Andric     return proxy_command->WantsCompletion();
3660b57cec5SDimitry Andric   return false;
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric 
HandleCompletion(CompletionRequest & request)3699dba64beSDimitry Andric void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
3700b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3710b57cec5SDimitry Andric   if (proxy_command)
3729dba64beSDimitry Andric     proxy_command->HandleCompletion(request);
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)3759dba64beSDimitry Andric void CommandObjectProxy::HandleArgumentCompletion(
3760b57cec5SDimitry Andric     CompletionRequest &request, OptionElementVector &opt_element_vector) {
3770b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3780b57cec5SDimitry Andric   if (proxy_command)
3799dba64beSDimitry Andric     proxy_command->HandleArgumentCompletion(request, opt_element_vector);
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
GetRepeatCommand(Args & current_command_args,uint32_t index)3820b57cec5SDimitry Andric const char *CommandObjectProxy::GetRepeatCommand(Args &current_command_args,
3830b57cec5SDimitry Andric                                                  uint32_t index) {
3840b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3850b57cec5SDimitry Andric   if (proxy_command)
3860b57cec5SDimitry Andric     return proxy_command->GetRepeatCommand(current_command_args, index);
3870b57cec5SDimitry Andric   return nullptr;
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
GetUnsupportedError()390af732203SDimitry Andric llvm::StringRef CommandObjectProxy::GetUnsupportedError() {
391af732203SDimitry Andric   return "command is not implemented";
392af732203SDimitry Andric }
393af732203SDimitry Andric 
Execute(const char * args_string,CommandReturnObject & result)3940b57cec5SDimitry Andric bool CommandObjectProxy::Execute(const char *args_string,
3950b57cec5SDimitry Andric                                  CommandReturnObject &result) {
3960b57cec5SDimitry Andric   CommandObject *proxy_command = GetProxyCommandObject();
3970b57cec5SDimitry Andric   if (proxy_command)
3980b57cec5SDimitry Andric     return proxy_command->Execute(args_string, result);
399*5f7ddb14SDimitry Andric   result.AppendError(GetUnsupportedError());
4000b57cec5SDimitry Andric   return false;
4010b57cec5SDimitry Andric }
402