<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! llvm-svn: 165861
This commit is contained in:
parent
88db3171dd
commit
998255bfe8
|
@ -412,13 +412,6 @@ public:
|
||||||
FindCommandsForApropos (const char *word,
|
FindCommandsForApropos (const char *word,
|
||||||
StringList &commands_found,
|
StringList &commands_found,
|
||||||
StringList &commands_help);
|
StringList &commands_help);
|
||||||
|
|
||||||
void
|
|
||||||
AproposAllSubCommands (CommandObject *cmd_obj,
|
|
||||||
const char *prefix,
|
|
||||||
const char *search_word,
|
|
||||||
StringList &commands_found,
|
|
||||||
StringList &commands_help);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GetBatchCommandMode () { return m_batch_command_mode; }
|
GetBatchCommandMode () { return m_batch_command_mode; }
|
||||||
|
|
|
@ -144,6 +144,31 @@ public:
|
||||||
virtual bool
|
virtual bool
|
||||||
IsMultiwordObject () { return false; }
|
IsMultiwordObject () { return false; }
|
||||||
|
|
||||||
|
virtual lldb::CommandObjectSP
|
||||||
|
GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL)
|
||||||
|
{
|
||||||
|
return lldb::CommandObjectSP();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual CommandObject *
|
||||||
|
GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
AproposAllSubCommands (const char *prefix,
|
||||||
|
const char *search_word,
|
||||||
|
StringList &commands_found,
|
||||||
|
StringList &commands_help)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
GenerateHelpText (CommandReturnObject &result)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// this is needed in order to allow the SBCommand class to
|
// this is needed in order to allow the SBCommand class to
|
||||||
// transparently try and load subcommands - it will fail on
|
// transparently try and load subcommands - it will fail on
|
||||||
// anything but a multiword command, but it avoids us doing
|
// anything but a multiword command, but it avoids us doing
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
virtual
|
virtual
|
||||||
~CommandObjectCrossref ();
|
~CommandObjectCrossref ();
|
||||||
|
|
||||||
void
|
virtual void
|
||||||
GenerateHelpText (CommandReturnObject &result);
|
GenerateHelpText (CommandReturnObject &result);
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
|
|
|
@ -46,15 +46,21 @@ public:
|
||||||
LoadSubCommand (const char *cmd_name,
|
LoadSubCommand (const char *cmd_name,
|
||||||
const lldb::CommandObjectSP& command_obj);
|
const lldb::CommandObjectSP& command_obj);
|
||||||
|
|
||||||
void
|
virtual void
|
||||||
GenerateHelpText (CommandReturnObject &result);
|
GenerateHelpText (CommandReturnObject &result);
|
||||||
|
|
||||||
lldb::CommandObjectSP
|
virtual lldb::CommandObjectSP
|
||||||
GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL);
|
GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL);
|
||||||
|
|
||||||
CommandObject *
|
virtual CommandObject *
|
||||||
GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL);
|
GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL);
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
AproposAllSubCommands (const char *prefix,
|
||||||
|
const char *search_word,
|
||||||
|
StringList &commands_found,
|
||||||
|
StringList &commands_help);
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
WantsRawCommandString() { return false; };
|
WantsRawCommandString() { return false; };
|
||||||
|
|
||||||
|
@ -88,6 +94,100 @@ protected:
|
||||||
bool m_can_be_removed;
|
bool m_can_be_removed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CommandObjectProxy : public CommandObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandObjectProxy (CommandInterpreter &interpreter,
|
||||||
|
const char *name,
|
||||||
|
const char *help = NULL,
|
||||||
|
const char *syntax = NULL,
|
||||||
|
uint32_t flags = 0);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~CommandObjectProxy ();
|
||||||
|
|
||||||
|
// Subclasses must provide a command object that will be transparently
|
||||||
|
// used for this object.
|
||||||
|
virtual CommandObject *
|
||||||
|
GetProxyCommandObject() = 0;
|
||||||
|
|
||||||
|
virtual const char *
|
||||||
|
GetHelpLong ();
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
AddObject (const char *obj_name);
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
IsCrossRefObject ();
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
IsRemovable() const;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
IsMultiwordObject ();
|
||||||
|
|
||||||
|
virtual lldb::CommandObjectSP
|
||||||
|
GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL);
|
||||||
|
|
||||||
|
virtual CommandObject *
|
||||||
|
GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL);
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
AproposAllSubCommands (const char *prefix,
|
||||||
|
const char *search_word,
|
||||||
|
StringList &commands_found,
|
||||||
|
StringList &commands_help);
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
LoadSubCommand (const char *cmd_name,
|
||||||
|
const lldb::CommandObjectSP& command_obj);
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
WantsRawCommandString();
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
WantsCompletion();
|
||||||
|
|
||||||
|
virtual Options *
|
||||||
|
GetOptions ();
|
||||||
|
|
||||||
|
|
||||||
|
virtual int
|
||||||
|
HandleCompletion (Args &input,
|
||||||
|
int &cursor_index,
|
||||||
|
int &cursor_char_position,
|
||||||
|
int match_start_point,
|
||||||
|
int max_return_elements,
|
||||||
|
bool &word_complete,
|
||||||
|
StringList &matches);
|
||||||
|
|
||||||
|
virtual int
|
||||||
|
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);
|
||||||
|
|
||||||
|
virtual const char *
|
||||||
|
GetRepeatCommand (Args ¤t_command_args,
|
||||||
|
uint32_t index);
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
Execute (const char *args_string,
|
||||||
|
CommandReturnObject &result);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// These two want to iterate over the subcommand dictionary.
|
||||||
|
friend class CommandInterpreter;
|
||||||
|
friend class CommandObjectSyntax;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
||||||
#endif // liblldb_CommandObjectMultiword_h_
|
#endif // liblldb_CommandObjectMultiword_h_
|
||||||
|
|
|
@ -1578,6 +1578,26 @@ public:
|
||||||
return !m_finalize_called;
|
return !m_finalize_called;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
/// Return a multi-word command object that can be used to expose
|
||||||
|
/// plug-in specific commands.
|
||||||
|
///
|
||||||
|
/// This object will be used to resolve plug-in commands and can be
|
||||||
|
/// triggered by a call to:
|
||||||
|
///
|
||||||
|
/// (lldb) process commmand <args>
|
||||||
|
///
|
||||||
|
/// @return
|
||||||
|
/// A CommandObject which can be one of the concrete subclasses
|
||||||
|
/// of CommandObject like CommandObjectRaw, CommandObjectParsed,
|
||||||
|
/// or CommandObjectMultiword.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
virtual CommandObject *
|
||||||
|
GetPluginCommandObject()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Launch a new process.
|
/// Launch a new process.
|
||||||
///
|
///
|
||||||
|
|
|
@ -599,8 +599,7 @@ protected:
|
||||||
{
|
{
|
||||||
const std::string sub_command = args.GetArgumentAtIndex(0);
|
const std::string sub_command = args.GetArgumentAtIndex(0);
|
||||||
assert (sub_command.length() != 0);
|
assert (sub_command.length() != 0);
|
||||||
subcommand_obj_sp =
|
subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
|
||||||
(((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
|
|
||||||
if (subcommand_obj_sp.get())
|
if (subcommand_obj_sp.get())
|
||||||
{
|
{
|
||||||
sub_cmd_obj = subcommand_obj_sp.get();
|
sub_cmd_obj = subcommand_obj_sp.get();
|
||||||
|
|
|
@ -103,8 +103,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CommandObject *found_cmd;
|
CommandObject *found_cmd;
|
||||||
found_cmd = ((CommandObjectMultiword *) sub_cmd_obj)->GetSubcommandObject(sub_command.c_str(),
|
found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
|
||||||
&matches);
|
|
||||||
if (found_cmd == NULL)
|
if (found_cmd == NULL)
|
||||||
all_okay = false;
|
all_okay = false;
|
||||||
else if (matches.GetSize() > 1)
|
else if (matches.GetSize() > 1)
|
||||||
|
@ -189,7 +188,7 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1);
|
m_interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1);
|
||||||
((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (result);
|
sub_cmd_obj->GenerateHelpText (result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -307,3 +307,232 @@ CommandObjectMultiword::GetRepeatCommand (Args ¤t_command_args, uint32_t i
|
||||||
return sub_command_object->GetRepeatCommand(current_command_args, index);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1071,7 +1071,6 @@ protected:
|
||||||
CommandOptions m_options;
|
CommandOptions m_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
OptionDefinition
|
OptionDefinition
|
||||||
CommandObjectProcessConnect::CommandOptions::g_option_table[] =
|
CommandObjectProcessConnect::CommandOptions::g_option_table[] =
|
||||||
{
|
{
|
||||||
|
@ -1079,6 +1078,39 @@ CommandObjectProcessConnect::CommandOptions::g_option_table[] =
|
||||||
{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
|
{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// 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
|
// CommandObjectProcessLoad
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
@ -1794,6 +1826,7 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter
|
||||||
LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
|
LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
|
||||||
LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
|
LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
|
||||||
LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
|
LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
|
||||||
|
LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
|
CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
|
||||||
|
|
|
@ -66,14 +66,12 @@ CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result)
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
{
|
{
|
||||||
std::string sub_command = command.GetArgumentAtIndex (i);
|
std::string sub_command = command.GetArgumentAtIndex (i);
|
||||||
if (! cmd_obj->IsMultiwordObject())
|
if (!cmd_obj->IsMultiwordObject())
|
||||||
all_okay = false;
|
all_okay = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.find (sub_command);
|
cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str());
|
||||||
if (pos != ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.end())
|
if (!cmd_obj)
|
||||||
cmd_obj = pos->second.get();
|
|
||||||
else
|
|
||||||
all_okay = false;
|
all_okay = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -763,8 +763,7 @@ CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliase
|
||||||
{
|
{
|
||||||
if (cmd_obj_sp->IsMultiwordObject())
|
if (cmd_obj_sp->IsMultiwordObject())
|
||||||
{
|
{
|
||||||
cmd_obj_sp = ((CommandObjectMultiword *) cmd_obj_sp.get())->GetSubcommandSP
|
cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j));
|
||||||
(cmd_words.GetArgumentAtIndex (j));
|
|
||||||
if (cmd_obj_sp.get() == NULL)
|
if (cmd_obj_sp.get() == NULL)
|
||||||
// The sub-command name was invalid. Fail and return the empty 'ret_val'.
|
// The sub-command name was invalid. Fail and return the empty 'ret_val'.
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
@ -1049,8 +1048,7 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
|
||||||
else if (cmd_obj->IsMultiwordObject ())
|
else if (cmd_obj->IsMultiwordObject ())
|
||||||
{
|
{
|
||||||
// Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
|
// Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
|
||||||
CommandObject *sub_cmd_obj =
|
CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
|
||||||
((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (cmd_word.c_str());
|
|
||||||
if (sub_cmd_obj)
|
if (sub_cmd_obj)
|
||||||
cmd_obj = sub_cmd_obj;
|
cmd_obj = sub_cmd_obj;
|
||||||
else // cmd_word was not a valid sub-command word, so we are donee
|
else // cmd_word was not a valid sub-command word, so we are donee
|
||||||
|
@ -1547,7 +1545,7 @@ CommandInterpreter::HandleCommand (const char *command_line,
|
||||||
{
|
{
|
||||||
if (cmd_obj->IsMultiwordObject ())
|
if (cmd_obj->IsMultiwordObject ())
|
||||||
{
|
{
|
||||||
CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str());
|
CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str());
|
||||||
if (sub_cmd_obj)
|
if (sub_cmd_obj)
|
||||||
{
|
{
|
||||||
actual_cmd_name_len += next_word.length() + 1;
|
actual_cmd_name_len += next_word.length() + 1;
|
||||||
|
@ -2721,35 +2719,6 @@ CommandInterpreter::OutputHelpText (Stream &strm,
|
||||||
strm.IndentLess(indent_size);
|
strm.IndentLess(indent_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word,
|
|
||||||
StringList &commands_found, StringList &commands_help)
|
|
||||||
{
|
|
||||||
CommandObject::CommandMap::const_iterator pos;
|
|
||||||
CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict;
|
|
||||||
CommandObject *sub_cmd_obj;
|
|
||||||
|
|
||||||
for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos)
|
|
||||||
{
|
|
||||||
const char * command_name = pos->first.c_str();
|
|
||||||
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())
|
|
||||||
AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found,
|
|
||||||
commands_help);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
|
CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
|
||||||
StringList &commands_help)
|
StringList &commands_help)
|
||||||
|
@ -2768,7 +2737,10 @@ CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_obj->IsMultiwordObject())
|
if (cmd_obj->IsMultiwordObject())
|
||||||
AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help);
|
cmd_obj->AproposAllSubCommands (command_name,
|
||||||
|
search_word,
|
||||||
|
commands_found,
|
||||||
|
commands_help);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,23 +377,19 @@ CommandObject::HandleCompletion
|
||||||
bool
|
bool
|
||||||
CommandObject::HelpTextContainsWord (const char *search_word)
|
CommandObject::HelpTextContainsWord (const char *search_word)
|
||||||
{
|
{
|
||||||
const char *short_help;
|
|
||||||
const char *long_help;
|
|
||||||
const char *syntax_help;
|
|
||||||
std::string options_usage_help;
|
std::string options_usage_help;
|
||||||
|
|
||||||
|
|
||||||
bool found_word = false;
|
bool found_word = false;
|
||||||
|
|
||||||
short_help = GetHelp();
|
const char *short_help = GetHelp();
|
||||||
long_help = GetHelpLong();
|
const char *long_help = GetHelpLong();
|
||||||
syntax_help = GetSyntax();
|
const char *syntax_help = GetSyntax();
|
||||||
|
|
||||||
if (strcasestr (short_help, search_word))
|
if (short_help && strcasestr (short_help, search_word))
|
||||||
found_word = true;
|
found_word = true;
|
||||||
else if (strcasestr (long_help, search_word))
|
else if (long_help && strcasestr (long_help, search_word))
|
||||||
found_word = true;
|
found_word = true;
|
||||||
else if (strcasestr (syntax_help, search_word))
|
else if (syntax_help && strcasestr (syntax_help, search_word))
|
||||||
found_word = true;
|
found_word = true;
|
||||||
|
|
||||||
if (!found_word
|
if (!found_word
|
||||||
|
|
|
@ -196,7 +196,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
|
||||||
m_waiting_for_attach (false),
|
m_waiting_for_attach (false),
|
||||||
m_destroy_tried_resuming (false),
|
m_destroy_tried_resuming (false),
|
||||||
m_dyld_plugin_name(),
|
m_dyld_plugin_name(),
|
||||||
m_kernel_load_addr (LLDB_INVALID_ADDRESS)
|
m_kernel_load_addr (LLDB_INVALID_ADDRESS),
|
||||||
|
m_command_sp ()
|
||||||
{
|
{
|
||||||
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
|
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
|
||||||
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
|
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
|
||||||
|
@ -3013,3 +3014,58 @@ ProcessGDBRemote::GetDynamicLoader ()
|
||||||
return m_dyld_ap.get();
|
return m_dyld_ap.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "lldb/Interpreter/CommandObject.h"
|
||||||
|
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||||
|
|
||||||
|
class CommandObjectProcessGDBRemotePacket : public CommandObjectParsed
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
public:
|
||||||
|
CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) :
|
||||||
|
CommandObjectParsed (interpreter,
|
||||||
|
"process plugin packet",
|
||||||
|
"Send a custom packet through the GDB remote protocol and print the answer.",
|
||||||
|
NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~CommandObjectProcessGDBRemotePacket ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoExecute (Args& command, CommandReturnObject &result)
|
||||||
|
{
|
||||||
|
printf ("CommandObjectProcessGDBRemotePacket::DoExecute() called!!!\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandObjectMultiwordProcessGDBRemote (CommandInterpreter &interpreter) :
|
||||||
|
CommandObjectMultiword (interpreter,
|
||||||
|
"process plugin",
|
||||||
|
"A set of commands for operating on a ProcessGDBRemote process.",
|
||||||
|
"process plugin <subcommand> [<subcommand-options>]")
|
||||||
|
{
|
||||||
|
LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket (interpreter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
~CommandObjectMultiwordProcessGDBRemote ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CommandObject *
|
||||||
|
ProcessGDBRemote::GetPluginCommandObject()
|
||||||
|
{
|
||||||
|
if (!m_command_sp)
|
||||||
|
m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter()));
|
||||||
|
return m_command_sp.get();
|
||||||
|
}
|
||||||
|
|
|
@ -71,8 +71,8 @@ public:
|
||||||
CanDebug (lldb_private::Target &target,
|
CanDebug (lldb_private::Target &target,
|
||||||
bool plugin_specified_by_name);
|
bool plugin_specified_by_name);
|
||||||
|
|
||||||
// virtual uint32_t
|
virtual lldb_private::CommandObject *
|
||||||
// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids);
|
GetPluginCommandObject();
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Creating a new process, or attaching to an existing one
|
// Creating a new process, or attaching to an existing one
|
||||||
|
@ -331,6 +331,7 @@ protected:
|
||||||
bool m_destroy_tried_resuming;
|
bool m_destroy_tried_resuming;
|
||||||
std::string m_dyld_plugin_name;
|
std::string m_dyld_plugin_name;
|
||||||
lldb::addr_t m_kernel_load_addr;
|
lldb::addr_t m_kernel_load_addr;
|
||||||
|
lldb::CommandObjectSP m_command_sp;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StartAsyncThread ();
|
StartAsyncThread ();
|
||||||
|
|
Loading…
Reference in New Issue