<rdar://problem/12491387>
I added the ability for a process plug-in to implement custom commands. All the lldb_private::Process plug-in has to do is override:
virtual CommandObject *
GetPluginCommandObject();
This object returned should be a multi-word command that vends LLDB commands. There is a sample implementation in ProcessGDBRemote that is hollowed out. It is intended to be used for sending a custom packet, though the body of the command execute function has yet to be implemented!
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@165861 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index 364c6f5..4c41d31 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -599,8 +599,7 @@
{
const std::string sub_command = args.GetArgumentAtIndex(0);
assert (sub_command.length() != 0);
- subcommand_obj_sp =
- (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
+ subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
if (subcommand_obj_sp.get())
{
sub_cmd_obj = subcommand_obj_sp.get();
diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp
index 5dfb105..3879005 100644
--- a/source/Commands/CommandObjectHelp.cpp
+++ b/source/Commands/CommandObjectHelp.cpp
@@ -103,8 +103,7 @@
else
{
CommandObject *found_cmd;
- found_cmd = ((CommandObjectMultiword *) sub_cmd_obj)->GetSubcommandObject(sub_command.c_str(),
- &matches);
+ found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
if (found_cmd == NULL)
all_okay = false;
else if (matches.GetSize() > 1)
@@ -189,7 +188,7 @@
}
else
m_interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1);
- ((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (result);
+ sub_cmd_obj->GenerateHelpText (result);
}
else
{
diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp
index e11d37b..9fcd40f 100644
--- a/source/Commands/CommandObjectMultiword.cpp
+++ b/source/Commands/CommandObjectMultiword.cpp
@@ -307,3 +307,232 @@
return sub_command_object->GetRepeatCommand(current_command_args, index);
}
+
+void
+CommandObjectMultiword::AproposAllSubCommands (const char *prefix,
+ const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help)
+{
+ CommandObject::CommandMap::const_iterator pos;
+
+ for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
+ {
+ const char * command_name = pos->first.c_str();
+ CommandObject *sub_cmd_obj = pos->second.get();
+ StreamString complete_command_name;
+
+ complete_command_name.Printf ("%s %s", prefix, command_name);
+
+ if (sub_cmd_obj->HelpTextContainsWord (search_word))
+ {
+ commands_found.AppendString (complete_command_name.GetData());
+ commands_help.AppendString (sub_cmd_obj->GetHelp());
+ }
+
+ if (sub_cmd_obj->IsMultiwordObject())
+ sub_cmd_obj->AproposAllSubCommands (complete_command_name.GetData(),
+ search_word,
+ commands_found,
+ commands_help);
+ }
+}
+
+
+
+CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help,
+ const char *syntax,
+ uint32_t flags) :
+ CommandObject (interpreter, name, help, syntax, flags)
+{
+}
+
+CommandObjectProxy::~CommandObjectProxy ()
+{
+}
+
+const char *
+CommandObjectProxy::GetHelpLong ()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetHelpLong();
+ return NULL;
+}
+
+void
+CommandObjectProxy::AddObject (const char *obj_name)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->AddObject (obj_name);
+}
+
+bool
+CommandObjectProxy::IsCrossRefObject ()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->IsCrossRefObject();
+ return false;
+}
+
+bool
+CommandObjectProxy::IsRemovable() const
+{
+ const CommandObject *proxy_command = const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->IsRemovable();
+ return false;
+}
+
+bool
+CommandObjectProxy::IsMultiwordObject ()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->IsMultiwordObject();
+ return false;
+}
+
+lldb::CommandObjectSP
+CommandObjectProxy::GetSubcommandSP (const char *sub_cmd, StringList *matches)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetSubcommandSP(sub_cmd, matches);
+ return lldb::CommandObjectSP();
+}
+
+CommandObject *
+CommandObjectProxy::GetSubcommandObject (const char *sub_cmd, StringList *matches)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetSubcommandObject(sub_cmd, matches);
+ return NULL;
+}
+
+void
+CommandObjectProxy::AproposAllSubCommands (const char *prefix,
+ const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->AproposAllSubCommands (prefix,
+ search_word,
+ commands_found,
+ commands_help);
+}
+
+bool
+CommandObjectProxy::LoadSubCommand (const char *cmd_name,
+ const lldb::CommandObjectSP& command_sp)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->LoadSubCommand (cmd_name, command_sp);
+ return false;
+}
+
+bool
+CommandObjectProxy::WantsRawCommandString()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->WantsRawCommandString();
+ return false;
+}
+
+bool
+CommandObjectProxy::WantsCompletion()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->WantsCompletion();
+ return false;
+}
+
+
+Options *
+CommandObjectProxy::GetOptions ()
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetOptions ();
+ return NULL;
+}
+
+
+int
+CommandObjectProxy::HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->HandleCompletion (input,
+ cursor_index,
+ cursor_char_position,
+ match_start_point,
+ max_return_elements,
+ word_complete,
+ matches);
+ matches.Clear();
+ return 0;
+}
+int
+CommandObjectProxy::HandleArgumentCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->HandleArgumentCompletion (input,
+ cursor_index,
+ cursor_char_position,
+ opt_element_vector,
+ match_start_point,
+ max_return_elements,
+ word_complete,
+ matches);
+ matches.Clear();
+ return 0;
+}
+
+const char *
+CommandObjectProxy::GetRepeatCommand (Args ¤t_command_args,
+ uint32_t index)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetRepeatCommand (current_command_args, index);
+ return NULL;
+}
+
+bool
+CommandObjectProxy::Execute (const char *args_string,
+ CommandReturnObject &result)
+{
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->Execute (args_string, result);
+ result.AppendError ("command is not implemented");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+}
+
+
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 5653e7a..41e216e 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -1071,7 +1071,6 @@
CommandOptions m_options;
};
-
OptionDefinition
CommandObjectProcessConnect::CommandOptions::g_option_table[] =
{
@@ -1080,6 +1079,39 @@
};
//-------------------------------------------------------------------------
+// CommandObjectProcessPlugin
+//-------------------------------------------------------------------------
+#pragma mark CommandObjectProcessPlugin
+
+class CommandObjectProcessPlugin : public CommandObjectProxy
+{
+public:
+
+ CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
+ CommandObjectProxy (interpreter,
+ "process plugin",
+ "Send a custom command to the current process plug-in.",
+ "process plugin <args>",
+ 0)
+ {
+ }
+
+ ~CommandObjectProcessPlugin ()
+ {
+ }
+
+ virtual CommandObject *
+ GetProxyCommandObject()
+ {
+ Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ return process->GetPluginCommandObject();
+ return NULL;
+ }
+};
+
+
+//-------------------------------------------------------------------------
// CommandObjectProcessLoad
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessLoad
@@ -1794,6 +1826,7 @@
LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
+ LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter)));
}
CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
diff --git a/source/Commands/CommandObjectSyntax.cpp b/source/Commands/CommandObjectSyntax.cpp
index d96542e..64308aa 100644
--- a/source/Commands/CommandObjectSyntax.cpp
+++ b/source/Commands/CommandObjectSyntax.cpp
@@ -66,14 +66,12 @@
for (int i = 1; i < argc; ++i)
{
std::string sub_command = command.GetArgumentAtIndex (i);
- if (! cmd_obj->IsMultiwordObject())
+ if (!cmd_obj->IsMultiwordObject())
all_okay = false;
else
{
- pos = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.find (sub_command);
- if (pos != ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.end())
- cmd_obj = pos->second.get();
- else
+ cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str());
+ if (!cmd_obj)
all_okay = false;
}
}