[Lldb-commits] [lldb] r232224 - Add support for Python object commands to return custom short and long help by implementing

Enrico Granata egranata at apple.com
Fri Mar 13 15:22:28 PDT 2015


Author: enrico
Date: Fri Mar 13 17:22:28 2015
New Revision: 232224

URL: http://llvm.org/viewvc/llvm-project?rev=232224&view=rev
Log:
Add support for Python object commands to return custom short and long help by implementing

def get_short_help(self)
def get_long_help(self)

methods on the command object

Also, add a test case for this feature


Modified:
    lldb/trunk/include/lldb/Interpreter/CommandObject.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/source/Commands/CommandObjectCommands.cpp
    lldb/trunk/source/Interpreter/CommandObject.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/test/functionalities/command_script/TestCommandScript.py
    lldb/trunk/test/functionalities/command_script/py_import
    lldb/trunk/test/functionalities/command_script/welcome.py

Modified: lldb/trunk/include/lldb/Interpreter/CommandObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObject.h?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObject.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObject.h Fri Mar 13 17:22:28 2015
@@ -98,7 +98,7 @@ public:
         return m_interpreter;
     }
 
-    const char *
+    virtual const char *
     GetHelp ();
 
     virtual const char *
@@ -114,6 +114,9 @@ public:
     SetHelp (const char * str);
 
     void
+    SetHelp (std::string str);
+    
+    void
     SetHelpLong (const char * str);
 
     void

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Fri Mar 13 17:22:28 2015
@@ -614,6 +614,22 @@ public:
     }
     
     virtual bool
+    GetShortHelpForCommandObject (lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                  std::string& dest)
+    {
+        dest.clear();
+        return false;
+    }
+
+    virtual bool
+    GetLongHelpForCommandObject (lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                 std::string& dest)
+    {
+        dest.clear();
+        return false;
+    }
+    
+    virtual bool
     CheckObjectExists (const char* name)
     {
         return false;

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Fri Mar 13 17:22:28 2015
@@ -214,6 +214,14 @@ public:
     GetDocumentationForItem (const char* item, std::string& dest) override;
     
     bool
+    GetShortHelpForCommandObject (lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                  std::string& dest) override;
+    
+    bool
+    GetLongHelpForCommandObject (lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                 std::string& dest) override ;
+    
+    bool
     CheckObjectExists (const char* name) override
     {
         if (!name || !name[0])

Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Fri Mar 13 17:22:28 2015
@@ -1435,6 +1435,8 @@ class CommandObjectScriptingObject : pub
 private:
     lldb::ScriptInterpreterObjectSP m_cmd_obj_sp;
     ScriptedCommandSynchronicity m_synchro;
+    bool m_fetched_help_short:1;
+    bool m_fetched_help_long:1;
     
 public:
     
@@ -1447,7 +1449,9 @@ public:
                       NULL,
                       NULL),
     m_cmd_obj_sp(cmd_obj_sp),
-    m_synchro(synch)
+    m_synchro(synch),
+    m_fetched_help_short(false),
+    m_fetched_help_long(false)
     {
         StreamString stream;
         stream.Printf("For more information run 'help %s'",name.c_str());
@@ -1476,10 +1480,38 @@ public:
     {
         return m_synchro;
     }
+
+    virtual const char *
+    GetHelp ()
+    {
+        if (!m_fetched_help_short)
+        {
+            ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
+            if (scripter)
+            {
+                std::string docstring;
+                m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
+                if (!docstring.empty())
+                    SetHelp(docstring);
+            }
+        }
+        return CommandObjectRaw::GetHelp();
+    }
     
     virtual const char *
     GetHelpLong ()
     {
+        if (!m_fetched_help_long)
+        {
+            ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
+            if (scripter)
+            {
+                std::string docstring;
+                m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
+                if (!docstring.empty())
+                    SetHelpLong(docstring);
+            }
+        }
         return CommandObjectRaw::GetHelpLong();
     }
     

Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Fri Mar 13 17:22:28 2015
@@ -124,6 +124,12 @@ CommandObject::SetHelp (const char *cstr
 }
 
 void
+CommandObject::SetHelp (std::string str)
+{
+    m_cmd_help_short = str;
+}
+
+void
 CommandObject::SetHelpLong (const char *cstr)
 {
     m_cmd_help_long = cstr;

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Fri Mar 13 17:22:28 2015
@@ -2793,6 +2793,156 @@ ScriptInterpreterPython::GetDocumentatio
     }
 }
 
+bool
+ScriptInterpreterPython::GetShortHelpForCommandObject (lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                                       std::string& dest)
+{
+    bool got_string = false;
+    dest.clear();
+    
+    Locker py_lock (this,
+                    Locker::AcquireLock | Locker::NoSTDIN,
+                    Locker::FreeLock);
+    
+    static char callee_name[] = "get_short_help";
+    
+    if (!cmd_obj_sp)
+        return false;
+    
+    PyObject* implementor = (PyObject*)cmd_obj_sp->GetObject();
+    
+    if (implementor == nullptr || implementor == Py_None)
+        return false;
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == nullptr || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return false;
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return false;
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    if (py_return != nullptr && py_return != Py_None)
+    {
+        if (PyString_Check(py_return))
+        {
+            dest.assign(PyString_AsString(py_return));
+            got_string = true;
+        }
+    }
+    Py_XDECREF(py_return);
+    
+    return got_string;
+}
+
+bool
+ScriptInterpreterPython::GetLongHelpForCommandObject (lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                                      std::string& dest)
+{
+    bool got_string = false;
+    dest.clear();
+    
+    Locker py_lock (this,
+                    Locker::AcquireLock | Locker::NoSTDIN,
+                    Locker::FreeLock);
+    
+    static char callee_name[] = "get_long_help";
+    
+    if (!cmd_obj_sp)
+        return false;
+    
+    PyObject* implementor = (PyObject*)cmd_obj_sp->GetObject();
+    
+    if (implementor == nullptr || implementor == Py_None)
+        return false;
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == nullptr || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return false;
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return false;
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    if (py_return != nullptr && py_return != Py_None)
+    {
+        if (PyString_Check(py_return))
+        {
+            dest.assign(PyString_AsString(py_return));
+            got_string = true;
+        }
+    }
+    Py_XDECREF(py_return);
+    
+    return got_string;
+}
+
 std::unique_ptr<ScriptInterpreterLocker>
 ScriptInterpreterPython::AcquireInterpreterLock ()
 {

Modified: lldb/trunk/test/functionalities/command_script/TestCommandScript.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/TestCommandScript.py?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/command_script/TestCommandScript.py (original)
+++ lldb/trunk/test/functionalities/command_script/TestCommandScript.py Fri Mar 13 17:22:28 2015
@@ -119,7 +119,7 @@ class CmdPythonTestCase(TestBase):
         self.runCmd("command script clear")
 
         # Test that re-defining an existing command works
-        self.runCmd('command script add my_command --function welcome.welcome_impl')
+        self.runCmd('command script add my_command --class welcome.WelcomeCommand')
         self.expect('my_command Blah', substrs = ['Hello Blah, welcome to LLDB'])
 
         self.runCmd('command script add my_command --function welcome.target_name_impl')

Modified: lldb/trunk/test/functionalities/command_script/py_import
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/py_import?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/command_script/py_import (original)
+++ lldb/trunk/test/functionalities/command_script/py_import Fri Mar 13 17:22:28 2015
@@ -2,7 +2,7 @@ script import sys, os
 script sys.path.append(os.path.join(os.getcwd(), os.pardir))
 script import welcome
 script import bug11569
-command script add welcome --function welcome.welcome_impl
+command script add welcome --class welcome.WelcomeCommand
 command script add targetname --function welcome.target_name_impl
 command script add longwait --function welcome.print_wait_impl
 command script import mysto.py --allow-reload

Modified: lldb/trunk/test/functionalities/command_script/welcome.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/welcome.py?rev=232224&r1=232223&r2=232224&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/command_script/welcome.py (original)
+++ lldb/trunk/test/functionalities/command_script/welcome.py Fri Mar 13 17:22:28 2015
@@ -1,12 +1,15 @@
 import sys
 
-def welcome_impl(debugger, args, result, dict):
-    """
-        Just a docstring for welcome_impl
-        A command that says hello to LLDB users
-    """
-    print >>result,  ('Hello ' + args + ', welcome to LLDB');
-    return None;
+class WelcomeCommand(object):
+    def __init__(self, debugger, session_dict):
+        pass
+    
+    def get_short_help(self):
+        return "Just a docstring for welcome_impl\nA command that says hello to LLDB users"
+        
+    def __call__(self, debugger, args, exe_ctx, result):
+        print >>result,  ('Hello ' + args + ', welcome to LLDB');
+        return None;
 
 def target_name_impl(debugger, args, result, dict):
     target = debugger.GetSelectedTarget()





More information about the lldb-commits mailing list