[Lldb-commits] [lldb] r138244 - in /lldb/trunk: scripts/Python/python-wrapper.swig source/Core/FormatManager.cpp source/Interpreter/ScriptInterpreterPython.cpp test/functionalities/alias/TestAliases.py test/functionalities/alias/py_import

Enrico Granata granata.enrico at gmail.com
Mon Aug 22 10:34:48 PDT 2011


Author: enrico
Date: Mon Aug 22 12:34:47 2011
New Revision: 138244

URL: http://llvm.org/viewvc/llvm-project?rev=138244&view=rev
Log:
- Support for Python namespaces:
  If you have a Python module foo, in order to use its contained objects in LLDB you do not need to use
  'from foo import *'. You can use 'import foo', and then refer to items in foo as 'foo.bar', and LLDB
  will know how to resolve bar as a member of foo.
  Accordingly, GNU libstdc++ formatters have been moved from the global namespace to gnu_libstdcpp and a few
  test cases are also updated to reflect the new convention. Python docs suggest using a plain 'import' en lieu of
  'from-import'.

Modified:
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/test/functionalities/alias/TestAliases.py
    lldb/trunk/test/functionalities/alias/py_import

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=138244&r1=138243&r2=138244&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Mon Aug 22 12:34:47 2011
@@ -1,5 +1,112 @@
 %wrapper %{
 
+class PyErr_Cleaner
+{
+public:
+    PyErr_Cleaner(bool print=false) :
+        m_print(print)
+    {
+    }
+
+    ~PyErr_Cleaner()
+    {
+        if (PyErr_Occurred())
+        {
+            if(m_print)
+                PyErr_Print();
+            PyErr_Clear();
+        }
+    }
+
+private:
+    bool m_print;
+};
+
+// resolve a dotted Python name in the form
+// foo.bar.baz.Foobar to an actual Python object
+// if pmodule is NULL, the __main__ module will be used
+// as the starting point for the search
+
+static PyObject*
+ResolvePythonName(const char* name,
+                  PyObject* pmodule = NULL)
+{
+
+    //printf("Resolving %s\n", name);
+
+    if (!name || !name[0])
+        return pmodule;
+
+    PyErr_Cleaner pyerr_cleanup(true);  // show Python errors
+
+    PyObject* main_dict;
+
+    if (!pmodule)
+    {
+        pmodule = PyImport_AddModule ("__main__");
+        if (!pmodule)
+            return NULL;
+    }
+
+    if (!PyDict_Check(pmodule))
+    {
+        main_dict = PyModule_GetDict (pmodule);
+        if (!main_dict)
+            return NULL;
+    }
+    else
+        main_dict = pmodule;
+
+    const char* dot_pos = ::strchr(name, '.');
+
+    PyObject *dest_object;
+    PyObject *key, *value;
+    Py_ssize_t pos = 0;
+
+    if (!dot_pos)
+    {
+        if (PyDict_Check (main_dict))
+        {
+            dest_object = NULL;   
+            while (PyDict_Next (main_dict, &pos, &key, &value))
+            {
+                // We have stolen references to the key and value objects in the dictionary; we need to increment 
+                // them now so that Python's garbage collector doesn't collect them out from under us.
+                Py_INCREF (key);
+                Py_INCREF (value);
+                //printf("Comparing %s and %s\n", name, PyString_AsString (key));
+                if (strcmp (PyString_AsString (key), name) == 0)
+                {
+                    dest_object = value;
+                    break;
+                }
+            }
+        }
+        
+        if (!dest_object || dest_object == Py_None)
+            return NULL;
+        return dest_object;
+    }
+    // foo.bar.ba
+    // 0123456789
+    // len = 3 - 0 
+    size_t len = dot_pos - name;
+    std::string piece(name,len);
+    dest_object = ResolvePythonName(piece.c_str(), main_dict);
+    //printf("Resolved %s to %p\n", piece.c_str(), dest_object);
+    if (!dest_object)
+        return NULL;
+    //printf("Now moving to resolve %s\n", dot_pos+1);
+    return ResolvePythonName(dot_pos+1,dest_object); // tail recursion.. should be optimized by the compiler
+
+}
+
+static PyObject*
+FindSessionDictionary(const char *session_dictionary_name)
+{
+    return ResolvePythonName(session_dictionary_name, NULL);
+}
+
 // This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...)
 // and is used when a script command is attached to a breakpoint for execution.
 
@@ -25,63 +132,18 @@
     if (!python_function_name || !session_dictionary_name)
         return stop_at_breakpoint;
 
-    PyObject *pmodule, *main_dict, *session_dict, *pfunc;
+    PyObject *session_dict, *pfunc;
     PyObject *pargs, *pvalue;
     
-    pmodule = PyImport_AddModule ("__main__");
-    if (pmodule != NULL)
+    session_dict = FindSessionDictionary (session_dictionary_name);
+    if (session_dict != NULL)
     {
-        main_dict = PyModule_GetDict (pmodule);
-        if (main_dict != NULL)
+        pfunc = ResolvePythonName (python_function_name, session_dict);
+        if (pfunc != NULL)
         {
-            PyObject *key, *value;
-            Py_ssize_t pos = 0;
-             
-            // Find the current session's dictionary in the main module's dictionary.
-
-            if (PyDict_Check (main_dict))
-            {
-                session_dict = NULL;   
-                while (PyDict_Next (main_dict, &pos, &key, &value))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), session_dictionary_name) == 0)
-                    {
-                        session_dict = value;
-                        break;
-                    }
-                }
-            }
-            
-            if (!session_dict || !PyDict_Check (session_dict))
-                return stop_at_breakpoint;
-                
-            // Find the function we need to call in the current session's dictionary.
-
-            pos = 0;
-            pfunc = NULL;
-            while (PyDict_Next (session_dict, &pos, &key, &value))
-            {
-                if (PyString_Check (key))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), python_function_name) == 0)
-                    {
-                        pfunc = value;
-                        break;
-                    }
-                }
-            }
-
             // Set up the arguments and call the function.
                 
-            if (pfunc && PyCallable_Check (pfunc))
+            if (PyCallable_Check (pfunc))
             {
                 pargs = PyTuple_New (3);
                 if (pargs == NULL)
@@ -144,63 +206,18 @@
     if (!python_function_name || !session_dictionary_name)
         return retval;
 
-    PyObject *pmodule, *main_dict, *session_dict, *pfunc;
+    PyObject *session_dict, *pfunc;
     PyObject *pargs, *pvalue;
     
-    pmodule = PyImport_AddModule ("__main__");
-    if (pmodule != NULL)
+    session_dict = FindSessionDictionary (session_dictionary_name);
+    if (session_dict != NULL)
     {
-        main_dict = PyModule_GetDict (pmodule);
-        if (main_dict != NULL)
+        pfunc = ResolvePythonName (python_function_name, session_dict);
+        if (pfunc != NULL)
         {
-            PyObject *key, *value;
-            Py_ssize_t pos = 0;
-             
-            // Find the current session's dictionary in the main module's dictionary.
-
-            if (PyDict_Check (main_dict))
-            {
-                session_dict = NULL;   
-                while (PyDict_Next (main_dict, &pos, &key, &value))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), session_dictionary_name) == 0)
-                    {
-                        session_dict = value;
-                        break;
-                    }
-                }
-            }
-            
-            if (!session_dict || !PyDict_Check (session_dict))
-                return retval;
-                
-            // Find the function we need to call in the current session's dictionary.
-
-            pos = 0;
-            pfunc = NULL;
-            while (PyDict_Next (session_dict, &pos, &key, &value))
-            {
-                if (PyString_Check (key))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), python_function_name) == 0)
-                    {
-                        pfunc = value;
-                        break;
-                    }
-                }
-            }
-
             // Set up the arguments and call the function.
                 
-            if (pfunc && PyCallable_Check (pfunc))
+            if (PyCallable_Check (pfunc))
             {
                 pargs = PyTuple_New (2);
                 if (pargs == NULL)
@@ -274,63 +291,18 @@
 
     const char* python_function_name = python_class_name.c_str();
 
-    PyObject *pmodule, *main_dict, *session_dict, *pfunc;
+    PyObject *session_dict, *pfunc;
     PyObject *pvalue;
-
-    pmodule = PyImport_AddModule ("__main__");
-    if (pmodule != NULL)
+    
+    session_dict = FindSessionDictionary (session_dictionary_name);
+    if (session_dict != NULL)
     {
-        main_dict = PyModule_GetDict (pmodule);
-        if (main_dict != NULL)
+        pfunc = ResolvePythonName (python_function_name, session_dict);
+        if (pfunc != NULL)
         {
-            PyObject *key, *value;
-            Py_ssize_t pos = 0;
-
-            // Find the current session's dictionary in the main module's dictionary.
-
-            if (PyDict_Check (main_dict))
-            {
-                session_dict = NULL;   
-                while (PyDict_Next (main_dict, &pos, &key, &value))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), session_dictionary_name) == 0)
-                    {
-                        session_dict = value;
-                        break;
-                    }
-                }
-            }
-
-            if (!session_dict || !PyDict_Check (session_dict))
-                return retval;
-
-            // Find the function we need to call in the current session's dictionary.
-
-            pos = 0;
-            pfunc = NULL;
-            while (PyDict_Next (session_dict, &pos, &key, &value))
-            {
-                if (PyString_Check (key))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), python_function_name) == 0)
-                    {
-                        pfunc = value;
-                        break;
-                    }
-                }
-            }
-
             // Set up the arguments and call the function.
-
-            if (pfunc && PyCallable_Check (pfunc))
+                
+            if (PyCallable_Check (pfunc))
             {
                 PyObject *argList = Py_BuildValue("SS", ValObj_PyObj, session_dict);
 
@@ -638,63 +610,18 @@
     if (!python_function_name || !session_dictionary_name)
         return retval;
 
-    PyObject *pmodule, *main_dict, *session_dict, *pfunc;
+    PyObject *session_dict, *pfunc;
     PyObject *pargs, *pvalue;
     
-    pmodule = PyImport_AddModule ("__main__");
-    if (pmodule != NULL)
+    session_dict = FindSessionDictionary (session_dictionary_name);
+    if (session_dict != NULL)
     {
-        main_dict = PyModule_GetDict (pmodule);
-        if (main_dict != NULL)
+        pfunc = ResolvePythonName (python_function_name, session_dict);
+        if (pfunc != NULL)
         {
-            PyObject *key, *value;
-            Py_ssize_t pos = 0;
-             
-            // Find the current session's dictionary in the main module's dictionary.
-
-            if (PyDict_Check (main_dict))
-            {
-                session_dict = NULL;   
-                while (PyDict_Next (main_dict, &pos, &key, &value))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), session_dictionary_name) == 0)
-                    {
-                        session_dict = value;
-                        break;
-                    }
-                }
-            }
-            
-            if (!session_dict || !PyDict_Check (session_dict))
-                return retval;
-                
-            // Find the function we need to call in the current session's dictionary.
-
-            pos = 0;
-            pfunc = NULL;
-            while (PyDict_Next (session_dict, &pos, &key, &value))
-            {
-                if (PyString_Check (key))
-                {
-                    // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                    // them now so that Python's garbage collector doesn't collect them out from under us.
-                    Py_INCREF (key);
-                    Py_INCREF (value);
-                    if (strcmp (PyString_AsString (key), python_function_name) == 0)
-                    {
-                        pfunc = value;
-                        break;
-                    }
-                }
-            }
-
             // Set up the arguments and call the function.
                 
-            if (pfunc && PyCallable_Check (pfunc))
+            if (PyCallable_Check (pfunc))
             {
                 pargs = PyTuple_New (4);
                 if (pargs == NULL)

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=138244&r1=138243&r2=138244&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Mon Aug 22 12:34:47 2011
@@ -447,17 +447,17 @@
                                      SyntheticChildrenSP(new SyntheticScriptProvider(true,
                                                                                      false,
                                                                                      false,
-                                                                                     "StdVectorSynthProvider")));
+                                                                                     "gnu_libstdcpp.StdVectorSynthProvider")));
     Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::map<")),
                                      SyntheticChildrenSP(new SyntheticScriptProvider(true,
                                                                                      false,
                                                                                      false,
-                                                                                     "StdMapSynthProvider")));
+                                                                                     "gnu_libstdcpp.StdMapSynthProvider")));
     Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::list<")),
                                      SyntheticChildrenSP(new SyntheticScriptProvider(true,
                                                                                      false,
                                                                                      false,
-                                                                                     "StdListSynthProvider")));
+                                                                                     "gnu_libstdcpp.StdListSynthProvider")));
     
     // DO NOT change the order of these calls, unless you WANT a change in the priority of these categories
     EnableCategory(m_system_category_name);

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=138244&r1=138243&r2=138244&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Aug 22 12:34:47 2011
@@ -175,7 +175,7 @@
     PyRun_SimpleString (run_string.GetData());
     
     run_string.Clear();
-    run_string.Printf ("run_one_line (%s, 'from gnu_libstdcpp import *')", m_dictionary_name.c_str(),
+    run_string.Printf ("run_one_line (%s, 'import gnu_libstdcpp')", m_dictionary_name.c_str(),
                        interpreter.GetDebugger().GetID());
     PyRun_SimpleString (run_string.GetData());
     

Modified: lldb/trunk/test/functionalities/alias/TestAliases.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/alias/TestAliases.py?rev=138244&r1=138243&r2=138244&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/alias/TestAliases.py (original)
+++ lldb/trunk/test/functionalities/alias/TestAliases.py Mon Aug 22 12:34:47 2011
@@ -152,10 +152,10 @@
 
         self.expect('command script list',
             substrs = ['targetname',
-                       'Run Python function target_name_impl'])
+                       'Run Python function welcome.target_name_impl'])
 
         self.expect("help targetname",
-                    substrs = ['Run Python function target_name_imp',
+                    substrs = ['Run Python function welcome.target_name_imp',
                                'This command takes \'raw\' input',
                                'quote stuff'])
 

Modified: lldb/trunk/test/functionalities/alias/py_import
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/alias/py_import?rev=138244&r1=138243&r2=138244&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/alias/py_import (original)
+++ lldb/trunk/test/functionalities/alias/py_import Mon Aug 22 12:34:47 2011
@@ -1,6 +1,6 @@
 script import sys, os
 script sys.path.append(os.path.join(os.getcwd(), os.pardir))
-script from welcome import *
-command script add welcome --function welcome_impl
-command script add targetname --function target_name_impl
-command script add longwait --function print_wait_impl
+script import welcome
+command script add welcome --function welcome.welcome_impl
+command script add targetname --function welcome.target_name_impl
+command script add longwait --function welcome.print_wait_impl





More information about the lldb-commits mailing list