[Lldb-commits] [lldb] r151708 - in /lldb/trunk: include/lldb/API/SBCommandInterpreter.h include/lldb/Interpreter/CommandObject.h include/lldb/lldb-private-interfaces.h include/lldb/lldb-types.h source/API/SBCommandInterpreter.cpp source/Interpreter/CommandInterpreter.cpp source/Interpreter/CommandObject.cpp tools/driver/Driver.cpp tools/driver/Driver.h
Greg Clayton
gclayton at apple.com
Tue Feb 28 20:21:24 PST 2012
Author: gclayton
Date: Tue Feb 28 22:21:24 2012
New Revision: 151708
URL: http://llvm.org/viewvc/llvm-project?rev=151708&view=rev
Log:
<rdar://problem/10605072>
Added the ability to override command line commands. In some cases GUI interfaces
might want to intercept commands like "quit" or "process launch" (which might cause
the process to re-run). They can now do so by overriding/intercepting commands
by using functions added to SBCommandInterpreter using a callback function. If the
callback function returns true, the command is assumed to be handled. If false
is returned the command should be evaluated normally.
Adopted this up in the Driver.cpp for intercepting the "quit" command.
Modified:
lldb/trunk/include/lldb/API/SBCommandInterpreter.h
lldb/trunk/include/lldb/Interpreter/CommandObject.h
lldb/trunk/include/lldb/lldb-private-interfaces.h
lldb/trunk/include/lldb/lldb-types.h
lldb/trunk/source/API/SBCommandInterpreter.cpp
lldb/trunk/source/Interpreter/CommandInterpreter.cpp
lldb/trunk/source/Interpreter/CommandObject.cpp
lldb/trunk/tools/driver/Driver.cpp
lldb/trunk/tools/driver/Driver.h
Modified: lldb/trunk/include/lldb/API/SBCommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCommandInterpreter.h?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBCommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/API/SBCommandInterpreter.h Tue Feb 28 22:21:24 2012
@@ -92,6 +92,13 @@
int max_return_elements,
lldb::SBStringList &matches);
+ // Catch commands before they execute by registering a callback that will
+ // get called when the command gets executed. This allows GUI or command
+ // line interfaces to intercept a command and stop it from happening
+ bool
+ SetCommandOverrideCallback (const char *command_name,
+ lldb::CommandOverrideCallback callback,
+ void *baton);
protected:
lldb_private::CommandInterpreter &
Modified: lldb/trunk/include/lldb/Interpreter/CommandObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObject.h?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObject.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObject.h Tue Feb 28 22:21:24 2012
@@ -194,11 +194,6 @@
eFlagProcessMustBePaused = (1 << 1)
};
- // Do not override this
- bool
- ExecuteCommandString (const char *command,
- CommandReturnObject &result);
-
bool
ParseOptions (Args& args,
CommandReturnObject &result);
@@ -369,6 +364,25 @@
return NULL;
}
+ CommandOverrideCallback
+ GetOverrideCallback () const
+ {
+ return m_command_override_callback;
+ }
+
+ void *
+ GetOverrideCallbackBaton () const
+ {
+ return m_command_override_baton;
+ }
+
+ void
+ SetOverrideCallback (CommandOverrideCallback callback, void *baton)
+ {
+ m_command_override_callback = callback;
+ m_command_override_baton = baton;
+ }
+
protected:
CommandInterpreter &m_interpreter;
std::string m_cmd_name;
@@ -376,9 +390,10 @@
std::string m_cmd_help_long;
std::string m_cmd_syntax;
bool m_is_alias;
- Flags m_flags;
+ Flags m_flags;
std::vector<CommandArgumentEntry> m_arguments;
-
+ CommandOverrideCallback m_command_override_callback;
+ void * m_command_override_baton;
// Helper function to populate IDs or ID ranges as the command argument data
// to the specified command argument entry.
static void
Modified: lldb/trunk/include/lldb/lldb-private-interfaces.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-interfaces.h?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-interfaces.h (original)
+++ lldb/trunk/include/lldb/lldb-private-interfaces.h Tue Feb 28 22:21:24 2012
@@ -35,6 +35,7 @@
typedef ThreadPlan * (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton);
typedef UnwindAssembly* (*UnwindAssemblyCreateInstance) (const ArchSpec &arch);
typedef int (*ComparisonFunction)(const void *, const void *);
+ typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
} // namespace lldb_private
Modified: lldb/trunk/include/lldb/lldb-types.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-types.h?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-types.h (original)
+++ lldb/trunk/include/lldb/lldb-types.h Tue Feb 28 22:21:24 2012
@@ -49,32 +49,8 @@
typedef void * thread_arg_t; // Host thread argument type
typedef void * thread_result_t; // Host thread result type
typedef void * (*thread_func_t)(void *); // Host thread function type
-
- // The template below can be used in a few useful ways:
- //
- // // Make a single shared pointer a class Foo
- // lldb::SharePtr<Foo>::Type foo_sp;
- //
- // // Make a typedef to a Foo shared pointer
- // typedef lldb::SharePtr<Foo>::Type FooSP;
- //
-// template<typename _Tp>
-// struct SharedPtr
-// {
-// typedef lldb_private::SharingPtr<_Tp> Type;
-// };
-// template<typename _Tp>
-// struct LoggingSharedPtr
-// {
-// typedef lldb_private::LoggingSharingPtr<_Tp> Type;
-// };
-//
-// template <typename _Tp>
-// struct IntrusiveSharedPtr
-// {
-// typedef lldb_private::IntrusiveSharingPtr<_Tp> Type;
-// };
- typedef void (*LogOutputCallback) (const char *, void *baton);
+ typedef void (*LogOutputCallback) (const char *, void *baton);
+ typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
} // namespace lldb
#if defined(__MINGW32__)
Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Tue Feb 28 22:21:24 2012
@@ -310,6 +310,22 @@
return CommandObject::GetArgumentDescriptionAsCString (arg_type);
}
+bool
+SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name,
+ lldb::CommandOverrideCallback callback,
+ void *baton)
+{
+ if (command_name && command_name[0] && m_opaque_ptr)
+ {
+ CommandObject *cmd_obj = m_opaque_ptr->GetCommandObject(command_name);
+ if (cmd_obj)
+ {
+ cmd_obj->SetOverrideCallback (callback, baton);
+ return true;
+ }
+ }
+ return false;
+}
#ifndef LLDB_DISABLE_PYTHON
@@ -341,3 +357,4 @@
#endif
}
}
+
Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Tue Feb 28 22:21:24 2012
@@ -1511,12 +1511,33 @@
log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str());
+ CommandOverrideCallback command_callback = cmd_obj->GetOverrideCallback();
+ bool handled = false;
if (wants_raw_input)
- cmd_obj->ExecuteRawCommandString (remainder.c_str(), result);
+ {
+ if (command_callback)
+ {
+ std::string full_command (cmd_obj->GetCommandName ());
+ full_command += ' ';
+ full_command += remainder;
+ const char *argv[2] = { NULL, NULL };
+ argv[0] = full_command.c_str();
+ handled = command_callback (cmd_obj->GetOverrideCallbackBaton(), argv);
+ }
+ if (!handled)
+ cmd_obj->ExecuteRawCommandString (remainder.c_str(), result);
+ }
else
{
Args cmd_args (remainder.c_str());
- cmd_obj->ExecuteWithOptions (cmd_args, result);
+ if (command_callback)
+ {
+ Args full_args (cmd_obj->GetCommandName ());
+ full_args.AppendArguments(cmd_args);
+ handled = command_callback (cmd_obj->GetOverrideCallbackBaton(), full_args.GetConstArgumentVector());
+ }
+ if (!handled)
+ cmd_obj->ExecuteWithOptions (cmd_args, result);
}
}
else
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Tue Feb 28 22:21:24 2012
@@ -53,7 +53,9 @@
m_cmd_syntax (),
m_is_alias (false),
m_flags (flags),
- m_arguments()
+ m_arguments(),
+ m_command_override_callback (NULL),
+ m_command_override_baton (NULL)
{
if (help && help[0])
m_cmd_help_short = help;
@@ -163,17 +165,6 @@
}
bool
-CommandObject::ExecuteCommandString
-(
- const char *command_line,
- CommandReturnObject &result
-)
-{
- Args command_args(command_line);
- return ExecuteWithOptions (command_args, result);
-}
-
-bool
CommandObject::ParseOptions
(
Args& args,
Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Tue Feb 28 22:21:24 2012
@@ -1088,6 +1088,14 @@
return bytes_len;
}
+// Intercept when the quit command is called and tell our driver that it is done
+static bool
+QuitCommandOverrideCallback (void *baton, const char **argv)
+{
+ ((Driver *)baton)->SetIsDone();
+ return true;
+}
+
void
Driver::MainLoop ()
{
@@ -1190,6 +1198,10 @@
SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
+ // Intercept when the quit command is called and tell our driver that it is done
+ bool quit_success = sb_interpreter.SetCommandOverrideCallback ("quit", QuitCommandOverrideCallback, this);
+ assert (quit_success);
+
m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
SBCommunication out_comm_2("driver.editline_output");
@@ -1371,8 +1383,7 @@
ReadyForCommand ();
- bool done = false;
- while (!done)
+ while (!GetIsDone())
{
listener.WaitForEvent (UINT32_MAX, event);
if (event.IsValid())
@@ -1385,12 +1396,15 @@
if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
(event_type & IOChannel::eBroadcastBitThreadDidExit))
{
- done = true;
+ SetIsDone();
if (event_type & IOChannel::eBroadcastBitThreadDidExit)
iochannel_thread_exited = true;
}
else
- done = HandleIOEvent (event);
+ {
+ if (HandleIOEvent (event))
+ SetIsDone();
+ }
}
else if (SBProcess::EventIsProcessEvent (event))
{
@@ -1402,9 +1416,12 @@
}
else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
{
+ // TODO: deprecate the eBroadcastBitQuitCommandReceived event
+ // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
+ // that can take over a command
if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
{
- done = true;
+ SetIsDone();
}
else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
{
Modified: lldb/trunk/tools/driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=151708&r1=151707&r2=151708&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.h (original)
+++ lldb/trunk/tools/driver/Driver.h Tue Feb 28 22:21:24 2012
@@ -135,6 +135,18 @@
return m_debugger.InputReaderIsTopReader (m_editline_reader);
}
+ bool
+ GetIsDone () const
+ {
+ return m_done;
+ }
+
+ void
+ SetIsDone ()
+ {
+ m_done = true;
+ }
+
private:
lldb::SBDebugger m_debugger;
lldb_utility::PseudoTerminal m_editline_pty;
@@ -143,6 +155,7 @@
std::auto_ptr<IOChannel> m_io_channel_ap;
OptionData m_option_data;
bool m_waiting_for_command;
+ bool m_done;
void
ResetOptionValues ();
More information about the lldb-commits
mailing list