[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